ASP.NET Web API中的symfony&paramconverter等价物

时间:2015-02-01 12:39:15

标签: c# asp.net asp.net-web-api

我是.Net社区的新人,请表示怜悯哈哈。我有两个问题

  1. ASP.NET中有symfony's @paramconverter注释的任何类似实现(例如转换器属性)吗? 例如请求URL,无论是GET / POST / PUT / DELETE,api请求都是id某个实体,我们能够将这样的id转换/绑定到实体对象(比如说productId in int并转换为Product对象)
  2. 预期的伪码:

    [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
        ....
    }
    
    1. 这是.Net中的好习惯吗?我要求这个实现,因为我认为这种模式能够减少重复代码,因为API请求主要依赖于对象id。如果这样的字符串找不到这样的Product对象,我甚至可以抛出异常。

1 个答案:

答案 0 :(得分:1)

看起来ModelBinder与交响乐的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的对象不存在,您甚至可以尝试调整此绑定器以返回响应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));