用于绑定部分参数的自定义参数绑定



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

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

所有其他模型都派生自我的基本模型。

在 Web API 中,我有我的客户控制器如下,

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 功能绑定?

下面是使用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();
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新