【问题标题】:ASP.Net MVC: What’s the Difference Between a Value Provider and Model BinderASP.Net MVC:值提供者和模型绑定器有什么区别
【发布时间】:2018-01-21 04:23:23
【问题描述】:

我正在阅读一篇关于 Value Provider and Model Binder 之间有什么区别的文章。

我了解 Model Binder 基本上是获取传入数据并构建对象。假设我正在发送学生数据,然后模型绑定器在从帖子到服务器并构建学生对象时抓取传入的学生数据。

但是还是不明白MVC中Value Provider的工作是什么。

那么请用简单的例子解释一下Value Provider做了什么样的工作以及模型绑定器做了什么?

不清楚 haacked.com 在说什么

DefaultModelBinder 将从 RouteData 中提取 Id 值并 构建时来自 JSON 的 Age、FirstName 和 LastName 值 人对象。之后,它将执行验证而无需 要知道各种值来自不同的来源。

当我发布 id、name、age 等时,为什么模型绑定器将仅从路由数据中选择 id,而从 JSON 中选择其余数据。模型绑定器应该从 RouteData 中选择所有值或从 JSON 中选择所有值........那么为什么只选择 id 呢?

mvc 中有多少种不同类型的值提供者?

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    ValueProviders 用于从请求中的不同来源获取数据

    ModelBinders 从 ValueProviders 获取数据来创建一个对象。他们不会直接从 Route Data 或 JSON 或某些特定数据中获取它,这不是他们的责任。

    • ASP.Net MVC 5 中可用的 ValueProviders 列表,按优先级排序:

      1. ChildActionValueProviderFactory
      2. FormValueProviderFactory
      3. JsonValueProviderFactory
      4. RouteDataValueProviderFactory
      5. QueryStringValueProviderFactory
      6. HttpFileCollectionValueProviderFactor
    • ASP.Net Web API 中可用的 ValueProviders 列表,按优先级排序:

      1. QueryStringValueProviderFactory
      2. RouteDataValueProviderFactory

    参考:专业 ASP.Net MVC 5,Wrox 版中的 Brad Wilson

    多个ValueProviders可以合作获取不同来源的数据。

    如果多次提供数据,优先级很重要。

    例如: id 来自查询字符串和 RouteData - RouteData 胜过查询字符串

    一切顺利

    【讨论】:

      【解决方案2】:

      我可能回答得太晚了,但我希望这对社区有用。

      与链接相关的第一点:Value Provider and Model Binder.

      1. ValueProvider :mvc 中的 ValueProvider 就像字典的解析源,帮助 modelbinder 为其模型获取适当的值。如果您查看接口 IValueProvider ,它有两种方法。包含前缀和 GetValue。 ContainPrefix 可帮助您识别子模型。例如人模型内部客户。像那样。

        • 如果您查看 DefaultModelBinder,如果您在 Query string 或 Form 或 RouteData 中指定,它将获得绑定值。 ValueProvider 在幕后提供帮助。 ModelBinder 它自己不知道。 ValueProvider 在 ModelBinder 下一层。
      2. 有很多类型的ValueProvider 是MVC。甚至您可以构建自己的价值提供者并在 Global.asax 中注册 MVC 框架。

        在 Global.asax 的 Application_Start 中

         protected void Application_Start()
            {
                // Other default configuration
                AreaRegistration.RegisterAllAreas();
                GlobalConfiguration.Configure(WebApiConfig.Register);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                var valueProviders = ValueProviderFactories.Factories;     // To Get List of ValueProviders. This list order is also important.       
            }
        
      3. 如果您查看实际链接 Peoson json 对象,它没有 Id 值,因此它将采用值 RouteData。如果您的 Person json 对象包含 Id 值,则有两个 Id 值来源。现在,无论哪个价值提供者先来,都会获得优先权。 (ValueProvider 列表)。如果 JsonValueProvider 先出现,则优先绑定 Id 值,如果 RouteDataValueProvider 先出现,则优先绑定 Id 值。

        要查看此内容,您可以在 global.asax application_start 中尝试这样的操作。 (在我的列表中 JsonValueProvider 排在第一位,所以我将其删除并最后添加)

        protected void Application_Start()
        {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        var valueProviders = ValueProviderFactories.Factories;
        ValueProviderFactories.Factories.RemoveAt(2); // My JsonValueProvider was at index 2.
        ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
        }
        

      【讨论】:

        【解决方案3】:

        模型绑定器(例如,与复杂类型的绑定)负责遍历类型图(即递归查找可绑定属性)并尝试查找这些属性的值。 binder 从值提供者那里获取这些值。

        想象一下,如果您要编写自己的模型绑定器,类似于复杂类型绑定器。这是不平凡的代码。因此,应该仔细决定是否要编写价值提供者或模型绑定器。你可以这样想“如果我创建一个 valueprovider,那么我就可以免费获得所有属性的递归绑定”。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-20
          • 2011-08-26
          • 2020-09-03
          • 2011-02-24
          • 1970-01-01
          相关资源
          最近更新 更多