首页 > 解决方案 > ASP.Net MVC 无法编辑用户,因为用户类中的 [比较(密码)]

问题描述

我有一个名为 Korisnik 的表(在我的语言上,在英语上是它的用户),我在我的 Controller 中添加了一个 Edit ActionResult ,但它不会工作,因为 [Compare("Lozinka")] 正在比较数据库中的密码和添加属性 PotvrdiLozinku,换句话说,我必须输入确认密码才能提交更改

namespace ProjekatFinalni.Models

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

public partial class Korisnik
{
    public int KorisnikID { get; set; }
    [DisplayName("Korisnicko ime:")]
    [Required(ErrorMessage ="Molimo vas unesite korisnicko ime.")]
    public string Korisnickoime { get; set; }

    [DisplayName("Lozinka:")]
    [DataType(DataType.Password)]
    [Required(ErrorMessage = "Molimo vas unesite lozinku.")]
    public string Lozinka { get; set; }

    [DisplayName("Admin:")]
    public bool DaLiJeAdmin { get; set; }
    [DisplayName("Gost:")]
    public bool Gost { get; set; }

    [DisplayName("Pravo za unos:")]
    public bool PravoUnosa { get; set; }

    [DisplayName("Potvrdi lozinku:")]
    [DataType(DataType.Password)]
    [Compare("Lozinka",ErrorMessage ="Lozinke se ne poklapaju.")]
    public string PotvrdiLozinku { get; set; }



    public string LoginErrorPoruka { get; set; }
}

这是我的控制器中的 Edit ActionResult

public ActionResult Edit(int id)
        {
            using (BazaProjekatEntities4 dbModel = new BazaProjekatEntities4())
            {
                return View(dbModel.Korisniks.Where(x => x.KorisnikID == id).FirstOrDefault());
            }
        }
        [HttpPost]
        public ActionResult Edit(int id,Korisnik k)
        {
            try
            {
                using (BazaProjekatEntities4 dbModel = new BazaProjekatEntities4())
                {
                    dbModel.Entry(k).State = EntityState.Modified;
                    dbModel.SaveChanges();
                }
                return RedirectToAction("Izlistaj");
             }
            catch
            {
                return View();
            }
        }

这是 Edit.cshtml

@model ProjekatFinalni.Models.Korisnik

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Korisnik</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.KorisnikID)

    <div class="form-group">
        @Html.LabelFor(model => model.Korisnickoime, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Korisnickoime, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Korisnickoime, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Lozinka, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Lozinka, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Lozinka, "", new { @class = "text-danger" })
        </div>
    </div>

       <div class="form-group">
        @Html.LabelFor(model => model.PotvrdiLozinku, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.PotvrdiLozinku, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.PotvrdiLozinku, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.DaLiJeAdmin, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <div class="checkbox">
                @Html.EditorFor(model => model.DaLiJeAdmin)
                @Html.ValidationMessageFor(model => model.DaLiJeAdmin, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Gost, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <div class="checkbox">
                @Html.EditorFor(model => model.Gost)
                @Html.ValidationMessageFor(model => model.Gost, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>



    <div class="form-group">
        @Html.LabelFor(model => model.PravoUnosa, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <div class="checkbox">
                @Html.EditorFor(model => model.PravoUnosa)
                @Html.ValidationMessageFor(model => model.PravoUnosa, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>



    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Sacuvaj" class="btn btn-default" />
        </div>
    </div>
</div>
}

只想编辑权限(Admin、Gost 和 PravoUnosa

编辑(添加了我使用的注册表单)

[HttpPost]
        public ActionResult DodajiliIzmeni(Korisnik korisnikmodel)
        {
            using (BazaProjekatEntities4 Modelkorisnik = new BazaProjekatEntities4())
            {
                if(Modelkorisnik.Korisniks.Any(x=> x.Korisnickoime == korisnikmodel.Korisnickoime))
                {
                    ViewBag.DuplicateMessage = "Korisnicko ime vec postoji.";
                    return View("DodajiliIzmeni", korisnikmodel);
                }
                Modelkorisnik.Korisniks.Add(korisnikmodel);
                Modelkorisnik.SaveChanges();
            }
            ModelState.Clear();
            ViewBag.SuccessMessage = "Registracija je uspela";



            return RedirectToAction("Index", "Login");
        }

标签: c#asp.net-mvc

解决方案


您应该为视图创建一个特定的视图模型,该模型具有视图需要的属性和验证属性,并使用它在视图和操作方法之间传输数据。

public class EditUserVm
{
    public int Id { get; set; }

    [DisplayName("Korisnicko ime:")]
    public string UserName { get; set; }

    [DisplayName("Admin:")]
    public bool Admin { get; set; }

    [DisplayName("Gost:")]
    public bool Gost { get; set; }

    [DisplayName("Pravo za unos:")]
    public bool PravoUnosa { get; set; }
}

现在,您将使用此视图模型为您的 GET 和 POST 操作方法。在您的 GET 操作方法中,首先创建此视图模型的对象,然后获取Korisniks传入的 Id 的对象,读取并将属性值映射到视图模型对象并将其传递给视图。

public ActionResult Edit(int id)
{
  using (var dbModel = new BazaProjekatEntities4())
  {
     var user = dbModel.Korisniks.FirstOrDefault(x => x.KorisnikID == id);
     // to do: If user is NULL, return a "Not found" view to user ?

     var vm = new EditUserVm { Id = id };
     vm.UserName = user.UserName;
     vm.Admin = user.Admin;
     vm.Gost = user.Gost;
     vm.PravoUnosa = user.PravoUnosa;
     return View(vm);
  }
}

现在确保您的视图被强类型化到此视图模型,因为我们正在将EditUserVm类的对象传递给它。

@model YourNamespaceGoesHere.EditUserVm
@using (Html.BeginForm())
{
  @Html.HiddenFor(a=>a.Id)
  <label>@Model.UserName</label>

  @Html.LabelFor(a=>a.Admin)
  @Html.CheckBoxFor(a=>a.Admin)

  @Html.LabelFor(a=>a.Gost)
  @Html.CheckBoxFor(a=>a.Gost)

  @Html.LabelFor(a=>a.PravoUnosa)
  @Html.CheckBoxFor(a=>a.PravoUnosa)

  <button type="submit" >Save</button>
}

现在您将使用与 action 方法参数相同的视图模型。在该方法中,我们将再次从数据库中读取 User 实体并仅更新我们想要的字段

[HttpPost]
public ActionResult Edit(EditUserVm model)
{
   var db = new BazaProjekatEntities4();
   var user = db.Korisniks.FirstOrDefault(x => x.KorisnikID == model.Id);
   // to do : Do a null check on user to be safe :)

   // Map the property values from view model to entity object
   user.Admin = model.Admin;
   user.Gost = model.Gost;
   user.PravoUnosa = model.PravoUnosa;

   db.Entry(k).State = EntityState.Modified;
   db.SaveChanges();

   return RedirectToAction("Index");
} 

简而言之,创建一个具有视图/代码绝对需要的属性的视图模型,并使用它在您的操作方法和视图之间传输数据。


推荐阅读