簡體   English   中英

MVC 5模型綁定器覆蓋

[英]MVC 5 Model Binder Override

我寫了一個模型Binder的覆蓋。

public override object BindModel(Controller context, ModelBindingContext bindingContext)
{
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

    object returnVal = null;

    if (value == null)
        returnVal = base.BindModel(controllerContext, bindingContext);
    else
    {
        /* custom logic here that never seems to get called.
            returnVal = something();
        */
    }

    return returnVal;
}

我還有一個javascript服務(在Angular中)向我的一個控制器發出一個AJAX請求。

AJAX請求嘗試發布一組int。 我嘗試單步執行模型綁定器,似乎value始終為null。 通過一些魔術, base.BindModel()仍然能夠將我的集合綁定到正確的C#對象。

這個問題是我不能使用我的自定義綁定器,因為從不調用else塊。 除了使用ValueProvider之外,還有其他方法可以獲得價值嗎?

我也相信在這個自定義綁定器正常工作之前(從內存可能是錯誤的)。 我最近從4.5更新到5.2.something。 是否有任何更新可以改變這種行為?

我還有一個javascript服務(在Angular中)向我的一個控制器發出一個AJAX請求。

...

這個問題是我不能使用我的自定義綁定器,因為從不調用else塊。

  • 我將假設您已在全局或在一個或多個參數上的操作本身上正確注冊了活頁夾。
  • 我還假設您的活頁夾在您預期時被調用。

它為null,因為它無法根據您嘗試綁定的模型名稱查找數據。 是否可以通過此名稱找到該值取決於型號名稱和客戶端請求中發送的必須對齊/匹配的數據。 但在任何人都可以告訴你為什么它不匹配的數據(包括你的模型與數組)可以通過以下三種方式之一從客戶端發送:

  1. 如果使用URL,您將在查詢字符串中重用相同的屬性名稱。 示例: ?myArray=1&myArray=2&myArray=3 這意味着在您的模型綁定器中,您將不得不考慮這一點。
  2. 如果在POST中使用data (正文),那么它可能是一個實際的數組對象。 json中的示例: {"myArray":[1,2,3,4]}
  3. 您可能還要序列化整個表單並使用Angular發送它( 這將允許您更好地使用MVC中的綁定功能

因此,為了更好地回答您的問題,您需要提供

  1. 數據的格式是從瀏覽器發送的以及它的發送方式(查詢字符串或數據有效負載)( 這可能在您的Angular工廠,服務或控制器中
  2. 您要綁定的模型定義

所以回顧一下: bindingContext.ModelName是期望的名稱,必須與模型綁定器試圖找到的數據匹配。 如果您要發送{"myArray":[1,2,3,4]}但您的模型屬性名為ProductIds那么它將始終為null。

我最近從4.5更新到5.2.something

不,不是我知道的。


最后的想法。 您還可以讓默認模型綁定器執行,然后在類型匹配時使用返回值執行某些操作。 如果綁定現在沒有問題,但你想做一些后處理,這將是一個更好的選擇。 例:

public override object BindModel(Controller context, ModelBindingContext bindingContext)
{
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

    object returnVal = base.BindModel(controllerContext, bindingContext);

    /* check returnVal and then additional custom logic here */.

    return returnVal;
}

請確保你做過這樣的事情: -

  1. 自定義模型綁定: -

     public class HomeCustomDataBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(HomePageModels)) { HttpRequestBase request = controllerContext.HttpContext.Request; string title = request.Form.Get("Title"); string day = request.Form.Get("Day"); string month = request.Form.Get("Month"); string year = request.Form.Get("Year"); return new HomePageModels { Title = title, Date = day + "/" + month + "/" + year }; //// call the default model binder this new binding context //return base.BindModel(controllerContext, newBindingContext); } else { return base.BindModel(controllerContext, bindingContext); } } } 
  2. 一旦我們完成了自定義類的編碼,我們將需要在Application_Start()下的Global.asax中注冊我所做的類。

     protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); ModelBinders.Binders.Add(typeof(HomePageModels), new HomeCustomBinder()); } 

    3)最后,我們需要告知控制器我們希望它使用的綁定。 我們可以使用屬性[ModelBinder(typeof(HomeCustomBinder))]指定如下:

     [HttpPost] public ActionResult Index([ModelBinder(typeof(HomeCustomBinder))] HomePageModels home) { if (ModelState.IsValid) { ViewBag.Title = home.Title; ViewBag.Date = home.Date; } return View(); } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM