ASP.NET Web API 中 symfony 的 paramconverter 等价物
symfony's paramconverter equivalent in ASP.NET Web API
我是.Net社区的新手,请手下留情哈哈。我有 两个问题:
- 在ASP.NET中是否有类似symfony's
@paramconverter
注解的实现(比如转换器属性)?
例如请求url,无论GET/POST/PUT/DELETE,带有id
某个实体的api请求,我们能够convert/bind这样的id到一个实体对象中(在 int 中说 productId
并转换为 Product
对象)
预期的伪代码:
[Route("products/{productId}/comments")]
[ProductConverter]
public HttpResponseMessage getProductComments(Product product) {
// product here not only with `productId` field, but already converted/bind into `Product`, through repository/data store
....
}
- 这是 .Net 中的良好做法吗?我要求这个实现是因为我认为这个模式能够减少重复代码,因为 API 请求主要依赖于对象
id
。如果这样的字符串找不到这样的 Product
对象,我什至可以抛出异常。
看起来ModelBinder 相当于symphony 的parmconverter。您可以在这里阅读更多相关信息:http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
示例如下:
首先你必须实现 IModelBinder。这是它的非常基本的实现:
public class ProductBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(Product))
{
return false;
}
var id = (int)bindingContext.ValueProvider.GetValue("productId").ConvertTo(typeof(int));
// Create instance of your object
bindingContext.Model = new Product { Id = id };
return true;
}
}
接下来您必须配置 ASP.NET WebApi 以使用该活页夹。在 WebApiConfig.cs 文件(或您配置 WebAPI 的任何其他地方)添加以下行:
config.BindParameter(typeof(Product), new ProductBinder());
最后一步是创建正确的控制器方法。提供正确的路由参数以正确绑定很重要。
[Route("products/{productId}/comments")]
public HttpResponseMessage getProductComments(Product product) {
}
我不认为这是不好的做法或好的做法。一如既往,这取决于。可以肯定的是,它减少了代码重复并为您的代码引入了一些顺序。如果带有 id
的对象不存在,您甚至可以尝试将此活页夹调整为 return 响应 404(未找到)
编辑:
将 IModelBinder
与依赖注入一起使用有点棘手,但仍然可行。您必须编写额外的扩展方法:
public static void BindParameter(this HttpConfiguration config, Type type, Type binderType)
{
config.Services.Insert(typeof(ModelBinderProvider), 0, new SimpleModelBinderProvider(type, () => (IModelBinder)config.DependencyResolver.GetService(binderType)));
config.ParameterBindingRules.Insert(0, type, param => param.BindWithModelBinding());
}
它基于找到的原始方法 there。唯一的区别是它期望活页夹的类型而不是实例。所以你只需调用:
config.BindParameter(typeof(Product), typeof(ProductBinder));
我是.Net社区的新手,请手下留情哈哈。我有 两个问题:
- 在ASP.NET中是否有类似symfony's
@paramconverter
注解的实现(比如转换器属性)? 例如请求url,无论GET/POST/PUT/DELETE,带有id
某个实体的api请求,我们能够convert/bind这样的id到一个实体对象中(在 int 中说productId
并转换为Product
对象)
预期的伪代码:
[Route("products/{productId}/comments")]
[ProductConverter]
public HttpResponseMessage getProductComments(Product product) {
// product here not only with `productId` field, but already converted/bind into `Product`, through repository/data store
....
}
- 这是 .Net 中的良好做法吗?我要求这个实现是因为我认为这个模式能够减少重复代码,因为 API 请求主要依赖于对象
id
。如果这样的字符串找不到这样的Product
对象,我什至可以抛出异常。
看起来ModelBinder 相当于symphony 的parmconverter。您可以在这里阅读更多相关信息:http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
示例如下:
首先你必须实现 IModelBinder。这是它的非常基本的实现:
public class ProductBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(Product))
{
return false;
}
var id = (int)bindingContext.ValueProvider.GetValue("productId").ConvertTo(typeof(int));
// Create instance of your object
bindingContext.Model = new Product { Id = id };
return true;
}
}
接下来您必须配置 ASP.NET WebApi 以使用该活页夹。在 WebApiConfig.cs 文件(或您配置 WebAPI 的任何其他地方)添加以下行:
config.BindParameter(typeof(Product), new ProductBinder());
最后一步是创建正确的控制器方法。提供正确的路由参数以正确绑定很重要。
[Route("products/{productId}/comments")]
public HttpResponseMessage getProductComments(Product product) {
}
我不认为这是不好的做法或好的做法。一如既往,这取决于。可以肯定的是,它减少了代码重复并为您的代码引入了一些顺序。如果带有 id
的对象不存在,您甚至可以尝试将此活页夹调整为 return 响应 404(未找到)
编辑:
将 IModelBinder
与依赖注入一起使用有点棘手,但仍然可行。您必须编写额外的扩展方法:
public static void BindParameter(this HttpConfiguration config, Type type, Type binderType)
{
config.Services.Insert(typeof(ModelBinderProvider), 0, new SimpleModelBinderProvider(type, () => (IModelBinder)config.DependencyResolver.GetService(binderType)));
config.ParameterBindingRules.Insert(0, type, param => param.BindWithModelBinding());
}
它基于找到的原始方法 there。唯一的区别是它期望活页夹的类型而不是实例。所以你只需调用:
config.BindParameter(typeof(Product), typeof(ProductBinder));