Метод обновления в MVC4 дает ошибку проверки - PullRequest
0 голосов
/ 14 октября 2018

У меня есть страница профиля пользователя, и я хочу, чтобы этот пользователь обновил только некоторые поля, и не может изменить свой адрес электронной почты или дату регистрации.но когда я хочу опубликовать это, я получаю ошибку проверки в тех полях, которые не в моем представлении.кстати у меня CUD в отдельном .cs.мои модели 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);
        }
    }

UserVM

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: 

1 Ответ

0 голосов
/ 14 октября 2018

Удалите это свойство из 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;
        }
    }
...