asp.net-mvc - MVC4 中的更新方法给出了验证错误
问题描述
我有一个用户个人资料页面,我希望该用户仅更新某些字段并且不能更改他的电子邮件或注册日期。但是当我想发布时,我在那些不在我视图中的字段中收到验证错误。顺便说一句,我在单独的 .cs 中有 CUD。我的 EF 模型位于 DomainModels 文件夹中,我用 EntityModels 文件夹中的另一个模型(具有验证)覆盖它们。这是代码:
控制器:
[HttpPost]
public ActionResult UserProfile(Merchant merchant)
{
MerchantRepository blMerchant = new MerchantRepository();
if (ModelState.IsValid)
{
if (blMerchant.Update(merchant))
{
return RedirectToAction("UserProfile");
//return MessageBox.Show("Product Edited Successfuly", MessageType.Success);
}
else
{
return MessageBox.Show(ModelState.GetErrors(), MessageType.Alert);
}
}
else
{
return MessageBox.Show(ModelState.GetErrors(), MessageType.Warning);
}
}
看法:
@using (Html.BeginForm("UserProfile", "Merchant", FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.id)
<label for="account-fn">Full Name</label>
@Html.TextBoxFor(model => model.Name, new { @class="form-control form-control-rounded" , @required="required"})
@Html.ValidationMessageFor(model => model.Name)
<label for="account-email">Phone</label>
@Html.TextBoxFor(model => model.Phone, new { @class = "form-control form-control-rounded", @required = "required" })
@Html.ValidationMessageFor(model => model.Phone)
<label>DOB</label>
@Html.TextBoxFor(model => model.Dob, new { @class = "form-control form-control-rounded" })
@Html.ValidationMessageFor(model => model.Dob)
@Html.CheckBoxFor(model => model.NewsLetter, new { @class = "input"})
<button class="btn btn-sm btn-primary m-r-5">Update Profile</button>
}
商户资料库
public bool Update(MySite.Models.DomainModels.Merchant entity, bool autoSave = true)
{
try
{
db.Merchants.Attach(entity);
db.Entry(entity).State = System.Data.Entity.EntityState.Modified;
if (autoSave)
return Convert.ToBoolean(db.SaveChanges());
else
return false;
}
catch
{
return false;
}
}
商户元数据
internal class MerchantMetaData
{
[ScaffoldColumn(false)]
[Bindable(false)]
public int id { get; set; }
[Required(ErrorMessage = "Please Enter Your Name", AllowEmptyStrings = false)]
[StringLength(50, ErrorMessage = "Please Enter Shorter Name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please Enter your Email Address", AllowEmptyStrings = false)]
public string Email { get; set; }
[ScaffoldColumn(false)]
public bool EmailConfirmed { get; set; }
[Required(ErrorMessage = "Please Enter your Password", AllowEmptyStrings = false)]
[DataType(DataType.Password)]
public string Password { get; set; }
[ScaffoldColumn(false)]
public int MembershipId { get; set; }
[ScaffoldColumn(false)]
[DataType(DataType.DateTime)]
public System.DateTime SignupDate { get; set; }
并且在namespace MySite.Models.DomainModels
[MetadataType(typeof(MySite.Models.EntityModels.MerchantMetaData))]
public partial class Merchant
{
[Compare("Password", ErrorMessage = "Confirm Password Doesn't Match The Field Above, Type Again !")]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
}
更新
我只使用这些文件创建了一个类,并将其映射为@StephenMuecke 所说的,但仍然出现验证错误:
[HttpGet]
public ActionResult UserProfile()
{
MerchantRepository blMerchant = new MerchantRepository();
var username = User.Identity.Name;
var UserData = blMerchant.Where(x => x.Email == username).SingleOrDefault();
var user=new UserVM();
user.id = UserData.id;
user.Name = UserData.Name;
user.Dob = DateTime.Now;
user.NewsLetter = UserData.NewsLetter;
user.Gender = UserData.Gender;
user.Phone = UserData.Phone;
return View(user);
}
[HttpPost]
public ActionResult UserProfile(UserVM user)
{
MerchantRepository blMerchant = new MerchantRepository();
var username = User.Identity.Name;
var merchant = blMerchant.Where(x => x.Email == username).SingleOrDefault();
merchant.id = user.id;
merchant.Name = user.Name;
merchant.Dob = user.Dob;
merchant.NewsLetter = user.NewsLetter;
merchant.Gender = user.Gender;
if (ModelState.IsValid)
{
if (blMerchant.Update(merchant))
{
return RedirectToAction("UserProfile");
//return MessageBox.Show("Product Edited Successfuly", MessageType.Success);
}
else
{
return MessageBox.Show(ModelState.GetErrors(), MessageType.Alert);
}
}
else
{
return MessageBox.Show(ModelState.GetErrors(), MessageType.Warning);
}
}
用户虚拟机
public class UserVM
{
public int id { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public string Phone { get; set; }
public DateTime Dob { get; set; }
public string Gender { get; set; }
public bool NewsLetter { get; set; }
}
错误------->
System.Data.Entity.Validation.DbEntityValidationException was caught
HResult=-2146232032
Message=Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at MySite.Models.Repositories.MerchantRepository.Update(Merchant entity, Boolean autoSave) in d:\MySite\MySite\Models\Repositories\MerchantRepository.cs:line 59
InnerException:
解决方案
从 Entity 中删除此属性并将其应用于 ViewModel。在更新数据时,您只更新了几个字段,而不是整个实体。
internal class MerchantMetaData
{
[ScaffoldColumn(false)]
[Bindable(false)]
public int id { get; set; }
[Required(ErrorMessage = "Please Enter Your Name", AllowEmptyStrings = false)]
[StringLength(50, ErrorMessage = "Please Enter Shorter Name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please Enter your Email Address", AllowEmptyStrings = false)]
public string Email { get; set; }
[ScaffoldColumn(false)]
public bool EmailConfirmed { get; set; }
[Required(ErrorMessage = "Please Enter your Password", AllowEmptyStrings = false)]
[DataType(DataType.Password)]
public string Password { get; set; }
[ScaffoldColumn(false)]
public int MembershipId { get; set; }
[ScaffoldColumn(false)]
[DataType(DataType.DateTime)]
public System.DateTime SignupDate { get; set; }
}
不要更新整个实体只更新您要更新的属性。
public bool Update(MySite.Models.DomainModels.Merchant entity, bool autoSave = true)
{
try
{
db.Entry(vR).Property(x => x.Name).IsModified = true;
db.Entry(vR).Property(x => x.Phone).IsModified = true;
db.Entry(vR).Property(x => x.Dob).IsModified = true;
db.Entry(vR).Property(x => x.NewsLetter).IsModified = true;
if (autoSave)
return Convert.ToBoolean(db.SaveChanges());
else
return false;
else
return false;
}
catch
{
return false;
}
}
推荐阅读
- android - 为什么在应用 View Binding 时 ConstraintlLayout 项目不可见?
- javascript - 单击按钮后按钮不会消失
- netlogo - Netlogo:将一种乌龟放在另一种类型上
- openscad - 在 Openscad 中设计 O 形环槽?
- spring - 在 Spring Boot 中使用 Firebase Id 令牌对用户进行身份验证
- c - 如何替换最近取消的宏“access_ok”的第一个参数?
- javascript - 为什么我的 CSS 悬停选择器不起作用?
- html - 即使使用绝对位置[CSS],如何换行文本
- android - 是否可以在 RadioButton 中使用视图?
- reactjs - React TypeError:无法读取未定义的属性“getBoundingClientRect”