如何在 Asp.Net Core 2.2 中使用带有自定义模型绑定的 [FromHeader] 属性

Iva*_*nyk 7 c# asp.net-web-api

我需要在我的请求中添加许多自定义标头。我可以使用这样的东西

public ActionResult Get([FromHeader, Required]string header1, [FromHeader]string  header2, ... , [FromHeader]string headerx)
{
...
...
}
Run Code Online (Sandbox Code Playgroud)

我不确定在一种方法中使用这么多参数是否好。我想使用这样的东西

public class HeaderParameters 
{
  [Required]
  public string Header1 { get; set; }
  public string Header2 { get; set; }
  ...
  public string Headerx { get; set; }
}

public ActionResult Get([FromHeader]HeaderParameters headerParameters)
{
  ...
  ...
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用。

如果我为 HeaderParameters 类的每个属性使用 [FromHeader] 属性,Swagger 就会表现得很奇怪。

请求示例 http://prntscr.com/p14kd7

{
  "errors": {
    "Device": [
      "The Header1 field is required."
    ]
  },
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "0HLPG9SNNJ1U2:00000001"
}
Run Code Online (Sandbox Code Playgroud)

Yur*_*ura 10

能够通过使用[FromHeader]模型属性上的属性和[FromQuery]模型本身上的属性来欺骗模型绑定来使其工作。这样的设置允许 Swagger 正确识别每个标头参数。

控制器端点示例:

    [HttpGet]
    [Route("headers")]
    public ActionResult<string> Get([FromQuery] HeadersParameters parameters = null)
    {
        return JsonConvert.SerializeObject(parameters);
    }
Run Code Online (Sandbox Code Playgroud)

HeadersParameters宣言:

    public class HeadersParameters
    {
        [FromHeader]
        [Required]
        public string Header1 { get; set; }

        [FromHeader]
        public string Header2 { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)


Mik*_*Mik 9

.Net Core 3.1 中的 ASP.NET Core 有一种更简单的方法。[FromHeader]到处放就行了,像这样:

[HttpPost("multipleHeaders")]
public IActionResult Post([FromHeader] ForecastHeaders forecastHeaders)
{
    try
    {
        Console.WriteLine($"Got a forecast for city: {forecastHeaders.City}," +
                            $"temperature: {forecastHeaders.TemperatureC} and" +
                            $"description: {forecastHeaders.Description}!");
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        return StatusCode(StatusCodes.Status500InternalServerError);
    }

    return new AcceptedResult();
}
Run Code Online (Sandbox Code Playgroud)

ForecastHeaders像这样:

public class ForecastHeaders
{
    [FromHeader]
    public string City { get; set; }

    [FromHeader]
    public int TemperatureC { get; set; }

    [FromHeader]
    public string Description { get; set; }

    [FromQuery]
    public string Sorting { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当您使用 Postman 发送请求时: 在此处输入图片说明

它就像一个魅力: 在此处输入图片说明

随便放就行[FromHeader]。也一起工作[FromQuery]


Iva*_*nyk 7

我创建了一个自定义属性以避免误解。

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FromHeaderModelAttribute : Attribute, IBindingSourceMetadata, IModelNameProvider
{
        public BindingSource BindingSource => BindingSource.Query;

        public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

所以,最终结果是:

[HttpGet]
[Route("headers")]
public ActionResult<string> Get([FromHeaderModel] HeadersParameters parameters = null)
{
    return JsonConvert.SerializeObject(parameters);
}

public class HeadersParameters
{
    [FromHeader]
    [Required]
    public string Header1 { get; set; }

    [FromHeader]
    public string Header2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)