3

モデルのプロパティに検証属性があります。モデルをビューに渡すと、検証は正常に機能します。ただし、そのモデルがビュー モデルのプロパティであり、コントローラーがビュー モデルをビューに渡すと、目立たない検証は機能しなくなり、コントローラーで検証されません。コントローラーへのモデル バインディングは、どちらの方法でも問題なく機能します。

ビューモデルのオブジェクトにドット表記を使用して隠しフィールドなどをバインドできる場合、目立たない検証も機能しないのはなぜですか?これを機能させる方法について誰かアドバイスがありますか?

ビューモデル(以下の最初のクラスはビューが使用するものです。最初のプロパティで「必須」かどうかは関係ありません)

public class PlanStakeholderViewModel : PlanGoalSelectorViewModel
{
    [Required]
    public PlanStakeholder PlanStakeholder { get; set; }
}
public class PlanGoalSelectorViewModel
{
    public IList<PlanGoal> AvailableGoals { get; set; }
    public IList<PlanGoal> SelectedGoals { get; set; }
    public PostedGoals PostedGoals { get; set; }
}

public class PostedGoals
{
    public string[] GoalIDs { get; set; }
}

見る

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    @Html.Hidden("PlanStakeholder.PlanID")
    @Html.Hidden("PlanStakeholder.Id")

    @Html.Partial("_Form")  

    <div class="editor-label"></div>
    <div class="editor-field">
        <input type="submit" value="Save" /> | @Html.ActionLink("Back to Plan", "Index", "Plan")
    </div>
}

VIEW_フォーム

@model Navigator.Views.ViewModels.PlanStakeholderViewModel

<div class="editor-label" style="vertical-align:top">
    @Html.LabelFor(model => model.PlanStakeholder.Name)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.PlanStakeholder.Name)
    @Html.ValidationMessageFor(model => model.PlanStakeholder.Name)
</div>

<div class="editor-label" style="vertical-align:top">
    @Html.LabelFor(model => model.PlanStakeholder.Relationship)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.PlanStakeholder.Relationship)
    @Html.ValidationMessageFor(model => model.PlanStakeholder.Relationship)
</div>

<div class="editor-label" style="vertical-align:top">
     <label>Associated Goals</label>
</div>
<div class="editor-field checkbox">
@Html.CheckBoxListFor(x => x.PostedGoals.GoalIDs,
                      x => x.AvailableGoals,          
                      x => x.Id,               
                      x => x.ShortTitle,               
                      x => x.SelectedGoals,
                      Position.Vertical)
</div>

モデル

public class PlanStakeholder : Base
{
    public PlanStakeholder()
    {
        PlanID = -1;
        Relationship = String.Empty;
        Name = String.Empty;
    }

    [Required]
    public int PlanID { get; set; }

    [Required]
    [MaxLength(50, ErrorMessage = "The {0} cannot be more than {1} characters.")]
    public string Relationship { get; set; }

    [Required]
    [MaxLength(50, ErrorMessage = "The {0} cannot be more than {1} characters.")]
    public string Name { get; set; }
}

UPDATE 1 以下は、Relationship プロパティのフォーム html の出力です。

<input class="text-box single-line" data-val="true" data-val-required="The Relationship field is required." id="PlanStakeholder_Relationship" name="PlanStakeholder.Relationship" type="text" value="Mom" />

以下はコントローラーのアクションです

[AuthorizeRoles(RoleSite.None, RoleOrg.OrgMember, RoleCohort.Client)]
public ActionResult Edit(int id, int planId)
{
    var plan = PlanManager.GetSingle(CurrentUser.UserId, CurrentOrg.Id);

    var model = new PlanStakeholderViewModel();
    model.PlanStakeholder = PlanStakeholderManager.GetSingle(id, CurrentUser.UserId);
    model.AvailableGoals = PlanGoalManager.GetList(plan.Id, CurrentUser.UserId);
    model.SelectedGoals = PlanGoalManager.GetRelatedToStakeholder(id, CurrentUser.UserId);

    if (model.Item.Id != id)
    {
        return HttpNotFound();
    }

    return View(model);
}

[HttpPost, ActionName("Edit")]
[AuthorizeRoles(RoleSite.None, RoleOrg.OrgMember, RoleCohort.Client)]
public ActionResult EditConfirmed(PlanStakeholderViewModel model)
{
    if (ModelState.IsValid)
    {
        ///DO STUFF
        return RedirectToAction("Index", "Plan");
    }
    return View(model);
}

更新 2 ビューで CheckBoxListFor をコメントアウトすると、すべて正常に動作します。この質問/問題を別の場所で取り上げる必要があるようです。コメントアウトされていない場合、モデルで許可されているよりも長い PlanStakeholder.Name の値を入力すると、@Html を含む行で asp.net エラーとして「値を null にすることはできません。パラメータ名: ソース」が表示されます。 .CheckBoxListFor.

4

1 に答える 1

0

これが、部分ビューを使用しない傾向がある理由の1つです。彼らにはあまりにも多くの落とし穴があり、あなたは様々な詳細を知らなければなりません。

私はEditorTemplatesを非常に好みます。コレクションを正しく処理し、ネストされたプロパティの適切な名前を生成します。そして、彼らはFormContextの問題を扱います。

しかし...とにかく。これを部分ビューの上部に追加します。

@{ ViewContext.FormContext = new FormContext(); }
于 2012-10-24T23:20:39.530 に答える