MVC学习系列——ModelBinder扩展

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MVC学习系列——ModelBinder扩展相关的知识,希望对你有一定的参考价值。

     在MVC系统中,我们接受数据,运用的是ModelBinder 的技术。

     MVC学习系列——ActionResult扩展在这个系列中,我们自定义了XmlResult的返回结果。

那么是不是意味着能POST一个XML数据类型给我们项目,这样的话,我们需要自定义一个XmlModelBinder来接受XML数据。

新建XmlModelBinder,继承于:IModelBinder

 1 public class XmlModelBinder : IModelBinder
 2     {
 3         public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
 4         {
 5             try
 6             {
 7                 var modelType = bindingContext.ModelType;
 8                 var serializer = new XmlSerializer(modelType);
 9                 var inputStream = controllerContext.HttpContext.Request.InputStream;
10                 return serializer.Deserialize(inputStream);
11             }
12             catch (Exception)
13             {
14                 throw;
15             }
16         }
17     }

在HomeController的PostXmlStudent中,运用:

1  public XmlResult PostXmlStudent([ModelBinder(typeof(XmlModelBinder))]StudentViewModel viewModel)
2         {
3             viewModel.Name = "Result";
4             //再次以XML的形式,返回结果
5             return new XmlResult(viewModel);
6         }

用Fiddler模拟一个以XML数据POST的请求
技术分享

接受数据:

技术分享

因为viewModel.Name = "Result";
所以,在Fiddler中查看返回数据:

技术分享

 

 

就这样,简单实现了:能够接收XML数据结构的功能

但是,这样做带来一个问题,就是每次需要XML的时候,就得加上[ModelBinder(typeof(XmlModelBinder))]这段代码,很是麻烦。

那么问题来了:MVC能不能自动识别。这个问题的答案是肯定的。

新建XmlModelBinderProvider,继承接口IModelBinderProvider

 1 public class XmlModelBinderProvider : IModelBinderProvider
 2     {
 3         public IModelBinder GetBinder(Type modelType)
 4         {
 5             var contentType = HttpContext.Current.Request.ContentType.ToLower();
 6 
 7             //如果不是Text/Xml,就返回null
 8             if (contentType!="text/xml")
 9             {
10                 return null;
11             }
12 
13             return new XmlModelBinder();
14         }
15     }

同时要注意的是:在Global类中,得注入。

 1  protected void Application_Start()
 2         {
 3             AreaRegistration.RegisterAllAreas();
 4             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
 5             RouteConfig.RegisterRoutes(RouteTable.Routes);
 6             BundleConfig.RegisterBundles(BundleTable.Bundles);
 7 
 8             //加载配置文件
 9             var logCfg = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "Log4Net.config");
10             XmlConfigurator.ConfigureAndWatch(logCfg);
11 
12             //XmlModelBinderProvider注入ModelBinderProviders
13             ModelBinderProviders.BinderProviders.Insert(0, new XmlModelBinderProvider());
14         }

新建一个Action,PostXmlStudent_Auto,特殊的是,没有用ModelBinder

1  public XmlResult PostXmlStudent_Auto(StudentViewModel viewModel)
2         {
3             viewModel.Name = "PostXmlStudent_Auto";
4             //再次以XML的形式,返回结果
5             return new XmlResult(viewModel);
6         }

用fiddle进行模拟请求:
技术分享

接受数据:

技术分享

因为 viewModel.Name = "PostXmlStudent_Auto";
,所以fiddle返回数据:

技术分享

 

以上是关于MVC学习系列——ModelBinder扩展的主要内容,如果未能解决你的问题,请参考以下文章

MVC学习系列——Model验证扩展

ModelBinder

如何在 MVC Web API 发布方法中将 ModelState 错误返回到 Kendo 网格?

MCS-51系列单片机系统功能的扩展

ASP.NET MVC 复制MVC项目代码到同一个项目的时候报错The request for ‘home’ has found the following matching controll(代码片

在使用 ModelBinder 之前更改文化