MVC3 - 帖子上的模型字段为空(使用viewmodel)

时间:2011-12-26 02:45:54

标签: asp.net-mvc-3 post viewmodel

在MVC3应用程序中,我有一个具有奇怪行为的实体:“创建”操作正常,但“编辑”操作失败:在提交时,我获取所有字段为空的模型。

我搜索了有关此错误的建议,似乎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; }
}

视图模型:

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 个答案:

答案 0 :(得分:5)

在视图中,您指定要绑定的模型为EmployeurFormViewModel

@model MyApp.ViewModels.EmployeurFormViewModel

但是,在您的控制器操作中,您指定:

[HttpPost]
public ActionResult Edit(tblEmployeur employeurCrt)

因此,我相信您需要在视图中指定:

@model [YOUR-NAMESPACE-HERE].tblEmployeur

然后在视图中引用模型的所有地方(例如)它将是model.wilaya而不是model.employeur.wilaya等。

您还需要更改以下内容的定义:

public tblEmployeur employeur { get; private set; }

为:

public tblEmployeur employeur { get; set; }

这样它可以由默认的模型绑定器设置,而不仅仅是由构造函数设置。

希望这有帮助。

答案 1 :(得分:1)

我回答问题的答案: 为什么“创建”操作正常,编辑没有:

查看型号:

public tblEmployeur employeur { get; private set; }

创建HttpPost操作:

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

编辑HttpPost操作:

public ActionResult Edit(tblEmployeur **employeurCrt**)

Create action参数的名称与ViewModel中属性的名称相同,而在Edit操作中名称则不同。

总之,以下两种解决方案都具有功能性:

  • public ActionResult Edit(tblEmployeur **employeur**)
    
    • 或:

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

(并为视图模型定义无参数构造函数)。

感谢Dangerous,希望这对其他人也有帮助。