0

わかりました、私はこれで公式に役に立たないです(前の質問を参照してください)

なぜ、私が以下を使用するとき、私はすべてうまく機能する素敵なチェックボックスリストを取得しますか:(拡張メソッドを使用して)

モデル

public class My : BusinessCategory
{
        public class MyTypes
        {
            public int MyTypeId { get; set; }
            public string MyTypeName { get; set; }
            public bool? MyTypeValue { get; set; }
        }
        public List<MyTypes> MyTypeListModel { get; set; }
}

意見

<fieldset>
    <legend>My Management</legend>
    <div style="text-align: left; padding-left: 47%;">
        @Html.CheckBoxListForListType(model => model.MyTypeListModel, (MultiSelectList)ViewBag.MyType, Model.ReviewId)
    </div>
    <p>
        <input type="submit" value="Continue" />
    </p>
</fieldset>

CheckBoxListForListType拡張機能(私が知っているひどい命名)

public static MvcHtmlString CheckBoxListForListType<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IEnumerable<TProperty>>> expression, MultiSelectList multiSelectList, Guid reviewId, object htmlAttributes = null)
        {
            //Derive property name for checkbox name
            MemberExpression body = expression.Body as MemberExpression;
            string propertyName = body.Member.Name;

            //Get currently select values from the ViewData model
            IEnumerable<TProperty> list = expression.Compile().Invoke(htmlHelper.ViewData.Model);

            //Convert selected value list to a List<string> for easy manipulation
            List<string> selectedValues = new List<string>();

            if (list != null)
            {
                selectedValues = new List<TProperty>(list).ConvertAll<string>(delegate(TProperty i) { return i.ToString(); });
            }

            //Create div
            TagBuilder divTag = new TagBuilder("div");
            divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);

            //Add checkboxes
            foreach (SelectListItem item in multiSelectList)
            {
                divTag.InnerHtml += String.Format("<div><input type=\"checkbox\" name=\"{0}\" id=\"{0}_{1}\" " +
                                                    "value=\"{1}\" {2} /><label for=\"{0}_{1}\">{3}</label></div>",
                                                    propertyName,
                                                    item.Value,
                                                    GetValueFromDatabaseList(reviewId, propertyName, item.Text.ToLower()),
                                                    item.Text);
            }

            return MvcHtmlString.Create(divTag.ToString());
        }

コントローラ

    public ActionResult My(Guid id)
        {
            try
            {
                var model = Model(id);
                SetMyTypeList(model.My);
                ViewBag.MyType = new MultiSelectList(model.My.MyTypeListModel, "MyTypeValue", "MyTypeName");
                return View(model.My);
            }
            catch (Exception ex)
            {
                ExceptionHelper.WriteLog(ex);
                return RedirectToAction("Error");
            }
        }

private void SetMyTypeList(My model)
        {
            model.MyTypeListModel = new List<My.MyTypes>();
            model.MyTypeListModel.Add(new My.MyTypes { MyTypeId = 1, MyTypeName = GetName.GetDisplayName(model, m => m.Option1), MyTypeValue = model.Option1});
            model.MyTypeListModel.Add(new My.MyTypes { MyTypeId = 2, MyTypeName = GetName.GetDisplayName(model, m => m. Option2), MyTypeValue = model.Option2 });
            model.MyTypeListModel.Add(new My.MyTypes { MyTypeId = 3, MyTypeName = GetName.GetDisplayName(model, m => m. Option3), MyTypeValue = model.Option3});
            model.MyTypeListModel.Add(new My.MyTypes { MyTypeId = 4, MyTypeName = GetName.GetDisplayName(model, m => m.Option4), MyTypeValue = model.Option4});         
        }

しかし、HttpPostアクションの結果を実行すると、MyTypeListModelはそのプロパティを「失います」。つまり、2つの選択が行われたが、名前、値、IDが存在しないことがわかります。

 [HttpPost]
    public ActionResult My(Guid id, My model)
    {
        try
        {
            model.ReviewId = id;
            var sessionModel = Model(id); 
            sessionModel.My = model;
            MapCheckBoxListResultswithDatabaseBoolsMy(model);
            UpdateDb(Categories.catMy, sessionModel);

            return RedirectToAction("BusinessSummary", new { id = sessionModel.ReviewId });
        }
        catch (Exception ex)
        {
            ExceptionHelper.WriteLog(ex);
            return RedirectToAction("Error");
        }
    }

タイプにリキャストする必要がありますか?その場合、どこにリキャストしますか?

いつものように、私のとりとめのないスレッドのように見えるものについて多くの謝罪。うまくいけば、物事はすぐにクリックし始めるでしょう:'(

4

1 に答える 1

0

アクションパラメーターを接続するプロセスはモデルバインディングと呼ばれ、デフォルトでは、MVCはフォーム、クエリ文字列、およびデータのルートに問い合わせて、タイプを入力しようとします。あなたの場合、問題はあなたのフォームフィールドがリストに期待するデフォルトの方法で名前が付けられていないことです。バインディングリストに関する情報は、PhilHaackによるこの記事にあります。サブプロパティを探しているので、タイプのプレフィックスを適切に付ける必要があることに注意してください。

私が便利だと思ったのは、ソースコードをASP.NET MVCに取得し、それをローカルでデバッグして、モデルのバインド時に何を探しているかを確認することです。

通常の規則に従わない場合は(それは賢明ですが)、タイプに応じて独自のカスタムモデルバインダーを指定できることを忘れないでください。

于 2012-07-06T13:07:41.623 に答える