【问题标题】:WebApi2: Custom parameter binding to bind partial parametersWebApi2:自定义参数绑定绑定部分参数
【发布时间】:2014-01-18 06:17:31
【问题描述】:

我有一个 webApi2 项目和另一个项目,其中我有我的模型类和一个作为所有模型基础的 BaseModel,如下所示,

public class BaseModel
{
    public string UserId { get; set; }
}

所有其他模型都是从我的 BaseModel 派生的。

在 webapi 中,我的 CustomerController 如下所示,

public class CustomerController : ApiController
{
    [HttpPost]
    public GetCustomerResponseModel Get(GetCustomerRequestModel requestModel)
    {
        var response = new GetCustomerResponseModel();

        //I need only the UserId coming from the BaseModel is binded from request headers
        var userId = requestModel.UserId;

        //I want all model data except UserId is binded with default model binding
        var customerData = requestModel.CustomerData;
        var someOtherData = requestModel.SomeOtherData;

        return response;
    }

    [HttpPost]
    public AddStockAlertResponseModel AddStockAlert(AddStockAlertRequestModel requestModel)
    {
        var response = new AddStockAlertResponseModel();

        //I need only the UserId coming from the BaseModel is binded from request headers
        var userId = requestModel.UserId;

        //I want all model data except UserId is binded with default model binding
        var stockInfo = requestModel.StockInfo;

        return response;
    }
}

到达 CustomerController 的每个请求在请求标头中都有一个“UserId”标头,我需要一个 ModelBinder 或 ParameterBinder 或一些仅绑定来自请求标头的 UserId 而不会触及其他模型参数的功能。我的意思是除了 UserId 之外的模型参数是默认绑定的..

我不想使用 AOP 或拦截器或方面。是否可以仅将 UserId 与 asp.net 功能(如模型绑定器、参数绑定器等)绑定。

【问题讨论】:

    标签: model-binding asp.net-web-api custom-model-binder asp.net-web-api2 parameterbinding


    【解决方案1】:

    以下是使用HttpParameterBinding 的快速示例。在这里,我创建了一个自定义参数绑定,让默认的基于 FromBody 的绑定使用格式化程序反序列化请求正文,然后从请求标头获取用户 ID 并设置在反序列化的对象上。 (您可能需要对以下代码添加额外的验证检查)。

    config.ParameterBindingRules.Insert(0, (paramDesc) =>
                {
                    if (typeof(BaseModel).IsAssignableFrom(paramDesc.ParameterType))
                    {
                        return new BaseModelParamBinding(paramDesc);
                    }
    
                    // any other types, let the default parameter binding handle
                    return null;
                });
    

    public class BaseModelParamBinding : HttpParameterBinding
    {
        HttpParameterBinding _defaultFromBodyBinding;
        HttpParameterDescriptor _paramDesc;
    
        public BaseModelParamBinding(HttpParameterDescriptor paramDesc)
            : base(paramDesc)
        {
            _paramDesc = paramDesc;
            _defaultFromBodyBinding = new FromBodyAttribute().GetBinding(paramDesc);
        }
    
        public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider,
            HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            await _defaultFromBodyBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
    
            BaseModel baseModel = actionContext.ActionArguments[_paramDesc.ParameterName] as BaseModel;
    
            if (baseModel != null)
            {
                baseModel.UserId = actionContext.Request.Headers.GetValues("UserId").First();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-12-09
      • 1970-01-01
      • 2014-02-08
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 2016-11-28
      • 2017-03-16
      • 1970-01-01
      相关资源
      最近更新 更多