web-dev-qa-db-ja.com

ASP.NET MVCビューモデルがDropDownListでHTTP Postにバインドされない

コントローラに投稿するとバインドが失われ、ビューモデルのすべてがNULLになるという問題があります。これが私が使用しているコードです:

表示:

@model ArticleCategoryVm

@using (@Html.BeginForm())
{
    @Html.HiddenFor(model => model.LanguageIdDisplayed)

    <label>Name: <span class="label label-important">Required</span></label>
    @Html.HmlValidationFor(model => model.CategoryName)
    @Html.TextBoxFor(model => model.CategoryName, new { maxlength = "255", placeholder = "Category Name", @class = "input-xlarge-fluid" })                  
    <span class="help-block">The is the name of the category and how it appears on the site.</span>

    <label>Language: <span class="label label-important">Required</span></label>
    @Html.HmlValidationFor(model => model.LanguageId)
    @Html.DropDownList("LanguageId", new SelectList(@Model.Languages, "Value", "Text"), "Select language", new { @class="input-xlarge-fluid" })
    <span class="help-block">This will be the language that the category is set too.</span>

    <label>Parent:</label>
    @Html.HmlValidationFor(model => model.CategoryParentId)
    @Html.DropDownList("CategoryParentId", new SelectList(@Model.CategoryParents, "Value", "Text"), new { @class = "input-xlarge-fluid" })
    <span class="help-block">Allows you to group the category under another existing category.</span>

    <label>Moderator Email: <span class="label label-important">Required</span></label>
    @Html.HmlValidationFor(model => model.ModeratorEmail)
    @Html.TextBoxFor(model => model.ModeratorEmail, new { maxlength = "255", placeholder = "Email Address", @class = "input-xlarge-fluid" })
    <span class="help-block">This is the moderator email for articles in this category.</span>

    <button type="submit" class="btn btn-duadua btn-small"><i class="icon-ok-3"></i> Add New Category</button>                      
}

ViewModel:

public class ArticleCategoryVm : BaseLayoutVm
{
    public int LanguageIdDisplayed;
    public List<ArticleCategoryItemVm> ArticleCategoryItemVms { get; set; }

    // Add Category Fields
    [Required]
    public string CategoryName;

    [EmailAttribute]
    [Required]
    public string ModeratorEmail;

    [Required]
    public int LanguageId;

    public int CategoryParentId;

    public List<SelectListItem> Languages { get; set; }
    public List<SelectListItem> CategoryParents { get; set; }
}

コントローラ:

[HttpPost]
public ActionResult Categories(ArticleCategoryVm vm)
{
   // Code here
   if (ModelState.IsValid)
   {
   }

   ReDrawDropDowns(vm);
   return View(vm)
}

ビューモデルのすべてがNULLになるのはなぜですか? Chromesツールを使用すると、文字列と整数の値が投稿に投稿されていることがわかります...回避策として、コードを機能させるために次のことを実行しました。

回避策コントローラー:

[HttpPost]
public ActionResult Categories(int LanguageIdDisplayed, string CategoryName, string ModeratorEmail, int LanguageId, int CategoryParentId)
{
    var vm = new ArticleCategoryVm()
    {
        CategoryName = CategoryName,
        LanguageIdDisplayed = LanguageIdDisplayed,
        ModeratorEmail = ModeratorEmail,
        LanguageId = LanguageId,
        CategoryParentId = CategoryParentId
    };

    if (ModelState.IsValid)
    {
    }

    ReDrawDropDowns(vm);
    return View(vm)
}

ありがとう

16
Danny Brady

この質問 に記載されているプロパティと変数の違いが原因である可能性があります。追加 { get; set; }をバインドするすべての変数に。その質問で述べたように、これはデフォルトのモデルバインダーがリフレクションを使用する方法が原因であると思います。

ASP.NET MVCソースコードを実際に取得してデバッグし、何が起こっているのかを確認できると便利であると過去に思いました。

40
Rob West

ビューでバインディングをモデル化するには、 strongly-typed-html-helpers を使用する必要があります

取り替える

@Html.DropDownList("CategoryParentId", new SelectList(@Model.CategoryParents, "Value", "Text"), new { @class = "input-xlarge-fluid" })

に:

@Html.DropDownListFor(model => model.CategoryParentId, new SelectList(@Model.CategoryParents, "Value", "Text"), new { @class = "input-xlarge-fluid" })
2