2

ドロップダウンリストをビューに表示したいので、ドロップダウンリストに入力するエントリのリストをビューに送信するモデル(ExampleAddSetupDto)に含めます。これは正常に機能しますが、検証エラーが発生し、受信モデルでビューを再表示すると、リストがnullになります。

私のアクションを以下に示します(注:ModelState.IsValidが失敗した場合に問題が発生します)。また、Autofacを使用して適切なサービスをメソッドに注入しているため、Actionメソッドの2番目のパラメーターが奇妙に見える場合があります)。

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Add(ExampleAddSetupDto add, IServiceAddCommit<IExampleAddSetupDto, IExampleAddCommitDto> service)
    {

        if (ModelState.IsValid)
        {
            var response = service.Create(add);
            if (response.IsValid)
            {
                TempData["message"] = "You successfully added a new Example Entry";
                return View("AddSuccess", response);
            }

            //else errors, so copy the errors over to the ModelState
            response.CopyErrorsToModelState(ModelState, add);
        }

        // Some validation error, so redisplay same view
        return View(add);

    }

私のモデルは次のようになります。

public class ExampleAddSetupDto : IExampleAddSetupDto
{

    [StringLength(50, MinimumLength = 2)]
    public string Name { get; set; }

    public int Option1Id { get; set; }

    public int Option2Id { get; set; }

    //-----------------------------
    //now the properties for the drop down lists 

    public IList<Option1> PosibleEntriesForOption1 { get; set; }
    public IList<Option2> PosibleEntriesForOption2 { get; set; }

}

私の見解は:

@model ServiceLayer.Example.DTOs.ExampleAddSetupDto

@{
    ViewBag.Title = "Add";
}

<h2>Add</h2>

<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>

@using (Html.BeginForm())
{  
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
    <legend>Add an Example item</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.Label("Option1")
        @Html.DropDownListFor(model => model.Option1Id, new SelectList(Model.PosibleEntriesForOption1, "Option1Id", "OptionText"))
        @Html.ValidationMessageFor(model => model.Option1Id)
    </div>
    <div class="editor-field">
        @Html.Label("Option2")
        @Html.DropDownListFor(model => model.Option2Id, new SelectList(Model.PosibleEntriesForOption2, "Option2Id", "OptionText"))
        @Html.ValidationMessageFor(model => model.Option2Id)
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>

}

Model.PosibleEntriesForOptionをフォームとともに返す必要があることを理解しています。ビューでHtml.HiddenForヘルパーを使用して、リストを返してみました。

@Html.HiddenFor(model => model.PosibleEntriesForOption1)

しかし、これはエラーをスローします'値'System.Collections.Generic.List`1[DataClasses.ExampleClasses.Option1]'は無効です。

明らかに私はここで何かが欠けているので、モデルを再表示してもエラーが発生しないようにリストを返す方法についてアドバイスをいただければ幸いです。

4

4 に答える 4

1

何らかの理由で、2つのリクエスト間でリスト全体を永続化する必要がある場合、これを行うための最善の方法は、次を使用することです。

TempData["EnterUniqueKeyHere"] = PossibleEntriesForOption1;

それを保存し、次に:

PossibleEntriesForOption1 = TempData["EnterUniqueKeyHere"] as IList<Option1>;

それを取得します。

TempDataに保存されているものはすべて、1回のリクエスト後に自動的に削除されることに注意してください。

于 2012-07-05T13:40:35.067 に答える
0

追加のgetアクションでは、これら2つのプロパティ(PosibleEntriesForOption1とPosibleEntriesForOption2)に適切な値を使用してモデルを作成します。これらはビューで適切に設定され、使用できるため、ドロップダウンはgetで正しくレンダリングされます。

POSTで、検証が失敗した場合、これらのプロパティを再度設定する必要があります。

 if (ModelState.IsValid)
    {
        // Do something
    }

    // before you redisplay the same view
    // set the properties PosibleEntriesForOption1 & PosibleEntriesForOption2

    // Some validation error, so redisplay same view
    return View(add);
于 2012-07-05T15:10:20.787 に答える
0

Dan NixonのTempData手法は一度は機能しますが、検証が再度失敗した場合、TempDataエントリはnullになります。私もリストをリロードする必要があると思います。

于 2012-08-16T18:14:42.383 に答える
0

検証が失敗した場合は、ドロップダウンリストに値のリストをロードする必要があります。そうでなければ、失敗します。

ビューを最初にロードすると、HttpGetメソッドが実行されると思います。HttpGetメソッドでは、ドロップダウンリストをバインドする必要があります

ページを送信すると、httpPostメソッドが実行され、問題がなければ送信されます。検証が失敗すると、HTTPPostメソッドが実行されますが、ドロップダウンのバインディングが見つかりません。

だからこれを試してみてください:あなたの場合

 if (ModelState.IsValid)
            {
                var response = service.Create(add);
                if (response.IsValid)
                {
                    TempData["message"] = "You successfully added a new Example Entry";
                    return View("AddSuccess", response);
                }

                //else errors, so copy the errors over to the ModelState
                response.CopyErrorsToModelState(ModelState, add);
            }
    else //if validation fails, you need to reload the dropdown and display your view.
      {
          // populate your dropdown again
              // You can add errors list into ModelState.
              ViewData.ModelState.AddModelError("What is the error", "Error Message, "What needs to be done by user, to get it work");
             return view(add)
      }
于 2012-07-05T13:38:36.580 に答える