MVC3 - поля модели пустые в посте (с использованием viewmodel) - PullRequest
2 голосов
/ 26 декабря 2011

В приложении MVC3 у меня есть объект со странным поведением: действие Create работает нормально, но действие Edit завершается неудачно: при отправке я получаю модель со всеми пустыми полями.

Я искал предложения по этой ошибке, кажется, что ViewModel может быть причиной, но я не вижу никаких проблем с моим. И как я уже говорил, творение работает отлично!

Пожалуйста, помогите, спасибо!

Модель:

    public partial class tblEmployeur
{
    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredUserIDMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "UserIDDisplay")]
    public System.Guid userID { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredNomMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "NomDisplay")]
    public string nom { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredTypeSocMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "TypeSocDisplay")]
    public string type_soc { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredCodeRCMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "CodeRCDisplay")]
    public string codeRC { get; set; }

    [Display(ResourceType = typeof(EmployeurResources), Name = "AdresseDisplay")]
    public string adresse { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredVilleMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "VilleDisplay")]
    public string ville { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredWilayaMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "WilayaDisplay")]
    public int wilaya { get; set; }

    [Display(ResourceType = typeof(EmployeurResources), Name = "Tel1Display")]
    public string tel1 { get; set; }

    [Display(ResourceType = typeof(EmployeurResources), Name = "Tel2Display")]
    public string tel2 { get; set; }

    [Display(ResourceType = typeof(EmployeurResources), Name = "FaxDisplay")]
    public string fax { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredEmailMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "EmailDisplay")]
    public string email { get; set; }

    [Display(ResourceType = typeof(EmployeurResources), Name = "SiteWebDisplay")]
    public string site_web { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredBanqueMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "BanqueDisplay")]
    public string banque { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredAgenceMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "AgenceDisplay")]
    public string agence { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredCompteMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "CompteDisplay")]
    public string nr_compte { get; set; }

    [Required(ErrorMessageResourceType = typeof(EmployeurResources), ErrorMessageResourceName = "RequiredDomaineMessage")]
    [Display(ResourceType = typeof(EmployeurResources), Name = "DomaineDisplay")]
    public int domaine { get; set; }

    [Display(ResourceType = typeof(EmployeurResources), Name = "NotesDisplay")]
    public string notes { get; set; }

    [Display(ResourceType = typeof(EmployeurResources), Name = "LogoPetitDisplay")]
    public byte[] logo_petit { get; set; }

    [Display(ResourceType = typeof(EmployeurResources), Name = "LogoGrandDisplay")]
    public byte[] logo_grand { get; set; }
}

ViewModel:

public class EmployeurFormViewModel
{
    // Properties
    public tblEmployeur employeur { get; private set; }
    public SelectList Domaines { get; private set; }
    public SelectList Wilayas { get; private set; }
    public SelectList TypesSocietes { get; private set; }
    public string ActionToPerform { get; private set; }


    // Constructor
    public EmployeurFormViewModel(tblEmployeur unEmployeur, Guid employeurID, SelectList domList, SelectList Wils, SelectList typesSocsList)
    {
        employeur = unEmployeur;
         Domaines = domList;
         Wilayas = Wils;
         TypesSocietes = typesSocsList;

        if (String.IsNullOrEmpty(unEmployeur.userID.ToString())||(string.Compare(unEmployeur.userID.ToString(), "00000000-0000-0000-0000-000000000000")==0))
        {
            unEmployeur.userID = employeurID;
            ActionToPerform = "Create";
        }
        else
        {
            ActionToPerform = "Edit";
        }
    }
}

Контроллер:

    [Authorize(Roles = "Employeur")]
    public ActionResult Create(Guid id)
    {
        tblEmployeur employeur = new tblEmployeur();
        SelectList domainesList = new SelectList(db.tblDomaines, "domaine_ID", "domaine");
        SelectList wilsList = new SelectList(db.tblWilayas, "wilaya_ID", "wilaya");
        SelectList typesSocList = new SelectList(typesSocRepository.GetAll());
        return View("Create", new EmployeurFormViewModel(employeur, id, domainesList, wilsList, typesSocList));
    }

    //
    // POST: /Employeur/Create

    [HttpPost, Authorize(Roles = "Employeur")]
    public ActionResult Create(tblEmployeur employeur, Guid id)
    {

        SelectList domainesList = new SelectList(db.tblDomaines, "domaine_ID", "domaine", employeur.domaine);
        SelectList wilsList = new SelectList(db.tblWilayas, "wilaya_ID", "wilaya");
        SelectList typesSocList = new SelectList(typesSocRepository.GetAll(), employeur.type_soc);

        IEnumerable<System.Data.Entity.Validation.DbEntityValidationResult> validationResultsColl = db.GetValidationErrors();

        foreach (var validationResults in validationResultsColl)
        {
            foreach (var error in validationResults.ValidationErrors)
            {
                ModelState.AddModelError(error.PropertyName, new Exception(error.ErrorMessage));
            }
        }

        if (ModelState.IsValid)
        {
            try
            {
                repository.Add(employeur);
                repository.Save();
                return RedirectToAction("Details");
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
            {
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        ModelState.AddModelError(validationError.PropertyName, new Exception(validationError.ErrorMessage));
                    }
                }
            }
            catch (Exception ex)
            {
                ModelState.AddOtherError(ex);
            }
        }
        return View("Create", new EmployeurFormViewModel(employeur, id, domainesList, wilsList, typesSocList));

    }

    //
    // GET: /Employeur/Edit/5


    public ActionResult Edit(Guid id)
    {
        tblEmployeur employeurCrt = db.tblEmployeurs.Find(id);
        SelectList domainesList = new SelectList(db.tblDomaines, "domaine_ID", "domaine", employeurCrt.domaine);
        SelectList wilsList = new SelectList(db.tblWilayas, "wilaya_ID", "wilaya", employeurCrt.wilaya);
        SelectList typesSocList = new SelectList(typesSocRepository.GetAll(), employeurCrt.type_soc);
        return View("Edit", new EmployeurFormViewModel(employeurCrt, id, domainesList, wilsList, typesSocList));
    }

    //
    // POST: /Employeur/Edit/5

    [HttpPost]
    public ActionResult Edit(tblEmployeur employeurCrt)
    {
        SelectList domainesList = new SelectList(db.tblDomaines, "domaine_ID", "domaine", employeurCrt.domaine);
        SelectList wilsList = new SelectList(db.tblWilayas, "wilaya_ID", "wilaya", employeurCrt.wilaya);
        SelectList typesSocList = new SelectList(typesSocRepository.GetAll(), employeurCrt.type_soc);

        IEnumerable<System.Data.Entity.Validation.DbEntityValidationResult> validationResultsColl = db.GetValidationErrors();

        foreach (var validationResults in validationResultsColl)
        {
            foreach (var error in validationResults.ValidationErrors)
            {
                ModelState.AddModelError(error.PropertyName, new Exception(error.ErrorMessage));
            }
        }

        if (ModelState.IsValid)
        {
            try
            {
                repository.Update(employeurCrt);
                repository.Save();
                return RedirectToAction("Details");
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
            {
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        ModelState.AddModelError(validationError.PropertyName, new Exception(validationError.ErrorMessage));
                    }
                }
            }
            catch (Exception ex)
            {
                ModelState.AddOtherError(ex);
            }
        }
        return View("Edit", new EmployeurFormViewModel(employeurCrt, employeurCrt.userID, domainesList, wilsList, typesSocList));
     }

Редактировать вид:

@model MyApp.ViewModels.EmployeurFormViewModel
@{
    ViewBag.Title = "Update employeur";
}
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<div class="text">
    <h1>
        Gestion du compte employeur</h1>
    <div style="height: 5px">
    </div>
    @using (Html.BeginForm())
    {

        @Html.ValidationSummary(false, "Sauvegarde échouée. Veuillez corriger les erreurs et réessayer.")
        <p>@Html.ValidationMessage("_FORM")</p>

        <div class="validation-summary-errors">
            <span></span>
            <ul>
            </ul>
        </div>
        <fieldset style="width: 800px; line-height: 1.8em;">
            <legend>Update</legend>
            <table style="width: 100%; padding-bottom: 0; padding-top: 0; border: 1">
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.nom)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.nom, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.nom, "*")
                        @Html.HiddenFor(model => model.employeur.userID, new { @class = "input_txt_nofloat" })
                        &nbsp;&nbsp;&nbsp;&nbsp;
                        @Html.DropDownList("employeur.type_soc", Model.TypesSocietes)
                        @Html.ValidationMessageFor(model => model.employeur.type_soc, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.codeRC)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.codeRC, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.codeRC, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.adresse)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.adresse, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.adresse, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.ville)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.ville, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.ville, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.wilaya)
                    </td>
                    <td style="border: 0;">
                        @Html.DropDownList("employeur.wilaya", Model.Wilayas, "Indiquez la wilaya", new { @style = "width: 232px;" })
                        @Html.ValidationMessageFor(model => model.employeur.wilaya)
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.tel1)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.tel1, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.tel1, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.tel2)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.tel2, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.tel2, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.fax)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.fax, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.fax, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.email)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.email, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.email, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.site_web)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.site_web, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.site_web, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.banque)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.banque, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.banque, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.agence)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.agence, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.agence, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.nr_compte)
                    </td>
                    <td style="border: 0;">
                        @Html.TextBoxFor(model => model.employeur.nr_compte, new { @class = "input_txt_nofloat" })
                        @Html.ValidationMessageFor(model => model.employeur.nr_compte, "*")
                    </td>
                </tr>
                <tr style="padding: 0 0 0 0; height: 32px">
                    <td style="width: 180px; border: 0;">
                        @Html.LabelFor(model => model.employeur.domaine)
                    </td>
                    <td style="border: 0;">
                        @Html.DropDownList("employeur.domaine", Model.Domaines, "Indiquez le domaine", new { @style = "width: 232px;" })
                        @Html.ValidationMessageFor(model => model.employeur.domaine, "*")
                    </td>
                </tr>
                <tr>
                    <td style="width: 180px; height: 60px; border: 0;">
                        &nbsp;
                    </td>
                    <td style="border: 0;">
                        <input type="submit" value="Sauvegarder" class="submit" />
                    </td>
                </tr>
            </table>
        </fieldset>
    }
    <div>
        @Html.ActionLink("Return", "Employeurs", "Home", null, new { @class = "link_no_underline" })
    </div>
</div>

Ответы [ 2 ]

5 голосов
/ 26 декабря 2011

В представлении вы указываете, что модель, к которой вы привязываете, является EmployeurFormViewModel:

@model MyApp.ViewModels.EmployeurFormViewModel

Однако в действии контроллера вы указываете:

[HttpPost]
public ActionResult Edit(tblEmployeur employeurCrt)

I, следовательнополагайте, что вам нужно будет указать в представлении:

@model [YOUR-NAMESPACE-HERE].tblEmployeur

, и тогда везде, где на модель ссылаются в представлении (например), это будет model.wilaya, а не model.employeur.wilaya и т. д.

Вам также необходимо изменить определение:

public tblEmployeur employeur { get; private set; }

на:

public tblEmployeur employeur { get; set; }

, чтобы его можно было установить с помощью связующего устройства модели по умолчанию, а не только с помощьюКонструктор.

Надеюсь, это поможет.

1 голос
/ 28 декабря 2011

Я возвращаюсь с ответом на вопрос: , почему действие «Создать» работало нормально, а «Правка» не выполнялось:

Просмотр модели:

public tblEmployeur employeur { get; private set; }

Создать действие HttpPost:

public ActionResult Create(tblEmployeur **employeur**, Guid id)

Изменить действие HttpPost:

public ActionResult Edit(tblEmployeur **employeurCrt**)

Имя параметра действия Создать было идентично имени свойства в ViewModel,в то время как в действии Edit имя было другим.

В заключение, оба следующих решения являются функциональными:

  • либо:

    public ActionResult Edit(tblEmployeur **employeur**)
    
    • или:

      public ActionResult Edit(EmployeurFormViewModel model) 
      { 
      tblEmployeur employeurCrt = model.employeur;
      ...
      

(и определение конструктора без параметров для модели представления).

Тысяча благодаряОпасно, надеюсь, это поможет кому-то еще.

...