ASP.NET Web API操作使用接口而不是具体类
我的团队需要使用此框架为我们的公司和产品开发框架.
其中一个要求是可以为特定客户定制产品,但应该使用同一产品的其他版本(不是自动)轻松更新. 我们正在使用ASP.NET MVC 4 Web API(目前,基于我们的框架,将在明年创建桌面产品),NHibernate,使用Autofac作为DI容器和N层的IoC. 因此,在WebApp的某些方面,我们将ViewModels用作具有一个默认实现的接口,并使用Autofac链接它们,并且在期货自定义中很容易更改. 在ASP.NET MVC中,我们实现了这个实现IModelBinderProvider并创建一个自定义类来激活DefaultModelBinder: 像这样的东西: public class MyCustomMVCModelBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(Type modelType) { if (modelType.IsInterface) return new MyCustomMVCModelBinder(); return new DefaultModelBinder(); } } public class MyCustomMVCModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { var context = new ModelBindingContext(bindingContext); var item = DependencyResolver.Current.GetService(bindingContext.ModelType); Func<object> modelAccessor = () => item; context.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(),bindingContext.ModelMetadata.ContainerType,modelAccessor,item.GetType(),bindingContext.ModelName); return base.BindModel(controllerContext,context); } } 在我的控制器中,我只使用接口作为参数.因此,它工作正常,因为值正确填充. 但是,如何在Web API中使用正确绑定的值执行相同操作? 这是WebAPI中的尝试实现: public class MyCustomWebAPIModelBinderProvider : ModelBinderProvider { public override IModelBinder GetBinder(System.Web.Http.HttpConfiguration configuration,Type modelType) { return new MyCustomWebAPIModelBinder(); } } public class MyCustomWebAPIModelBinder : IModelBinder { public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext,ModelBindingContext bindingContext) { if (bindingContext.ModelType.IsInterface) { var item = GlobalConfiguration.Configuration.DependencyResolver.GetService(bindingContext.ModelType); if (item != null) { Func<object> modelAccessor = () => item; var a = bindingContext.ModelMetadata.ContainerType; var b = modelAccessor; var c = item.GetType(); var d = bindingContext.ModelName; bindingContext.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(),a,b,c,d); bindingContext.Model = item; return true; } } return false; } } 我错过了什么? 解决方法
而不是使用ModelBinder,使用MediaTypeFormatter的实现.
您可以覆盖方法“ReadFromStreamAsync”并将类型更改为您需要的任何类型. 在下面的示例中,通过使用MVC的DependencyResolver解析具体类型来更改类型,对WebAPI可以正常工作. public class CustomFormUrlEncodedMediaTypeFormatter : FormUrlEncodedMediaTypeFormatter { public CustomFormUrlEncodedMediaTypeFormatter() : base() { } public override Task ReadFromStreamAsync(Type type,Stream readStream,HttpContent content,IFormatterLogger formatterLogger) { if (type.IsInterface) type = GetConcreteType(type); return base.ReadFromStreamAsync(type,readStream,content,formatterLogger); } public override Task WriteToStreamAsync(Type type,object value,Stream writeStream,TransportContext transportContext) { if (type.IsInterface) type = GetConcreteType(type); return base.WriteToStreamAsync(type,value,writeStream,transportContext); } private Type GetConcreteType(Type type) { object concrete = System.Web.Mvc.DependencyResolver.Current.GetService(type); return concrete.GetType(); } } 如果你想用JsonFormatter做到这一点,那么为Json.NET创建一个“CustomCreationConverter”是一个更好的方法,而不是解决你的界面中所有子对象的依赖性. public class DomainConverter : CustomCreationConverter { public DomainConverter() { } public override bool CanConvert(Type objectType) { return objectType.IsInterface; } public override object Create(Type objectType) { return System.Web.Mvc.DependencyResolver.Current.GetService(objectType); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 如何在我的代码中使用接口使其更加scalabale?
- .net – 在没有区域的控制器中创建子文件夹
- asp.net-core – ASP.NET Core Web Application控制台立即关
- asp.net-mvc-3 – 强类型的RadioButtonlist
- asp.net – 在SessionPageStatePersister中保持ViewState
- asp.net-core – 如何在AutoMapper配置文件类中注入服务
- 从数据到代码——通过代码生成机制实现强类型编程[上篇]
- ASP.NET -- WebForm -- Session的使用
- 【DevExpress v17.2新功能预告】DevExpress ASP.NET Schedu
- asp.net-mvc – ASP.NET MVC是否容易受到oracle的填充攻击?