繁体   English   中英

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

[英]How to use [FromHeader] attribute with custom model binding in Asp.Net Core 2.2

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

public ActionResult Get([FromHeader, Required]string header1, [FromHeader]string  header2, ... , [FromHeader]string headerx)
{
...
...
}

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

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)
{
  ...
  ...
}

但它不起作用。

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

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

{
  "errors": {
    "Device": [
      "The Header1 field is required."
    ]
  },
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "0HLPG9SNNJ1U2:00000001"
}

.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();
}

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; }
}

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

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

只需将[FromHeader]放在任何地方。 也可以使用[FromQuery]

能够使它发挥作用,通过使用[FromHeader]上模特属性属性和[FromQuery]对模型本身的属性来糊弄模型绑定。 这种设置允许 Swagger 正确识别每个标头参数。

控制器端点示例:

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

HeadersParameters声明:

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

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

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

[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; }
}

所以,最后的结果是:

[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; }
}

我知道这是一篇旧帖子,但由于没有公认的答案。 这也是基于 ASP.NET Core 6。您可以组合多个属性 Required、RegularExpression 和 FromHeader,如下所示。

        public async Task<IActionResult> DeleteUserAsync(
        [Required]
        [RegularExpression(@"[1-9]*", ErrorMessage = "Must be greater then zero.")]
        [FromHeader(Name = "x-tenant-id")] 
        long xTenantId, 
        [FromRoute] long id)

这对某人有何帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM