简体   繁体   English

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

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

I need to add many custom headers in my request.我需要在我的请求中添加许多自定义标头。 I can use something like this我可以用这样的东西

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

I am not sure if it is good to use that number of parameters in one method.我不确定在一种方法中使用那么多参数是否好。 I would like to use something like this我想用这样的东西

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

But it doesn't work.但它不起作用。

If I use [FromHeader] attribute for each property of HeaderParameters class Swagger is acting weird.如果我对 HeaderParameters class Swagger 的每个属性使用 [FromHeader] 属性,就会表现得很奇怪。

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

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

There is an easier way in ASP.NET Core in .Net Core 3.1. .Net Core 3.1 中的 ASP.NET Core 有一种更简单的方法。 Just put [FromHeader] everywhere, like this:只需将[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();
}

And ForecastHeaders look like this: 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; }
}

And when you send a request with Postman:当您使用 Postman 发送请求时: 在此处输入图片说明

It works like a charm:它就像一个魅力: 在此处输入图片说明

Just put [FromHeader] everywhere.只需将[FromHeader]放在任何地方。 Work with [FromQuery] as well.也可以使用[FromQuery]

Was able to make it work by using [FromHeader] attribute on model properties and [FromQuery] attribute on model itself to fool model binding.能够使它发挥作用,通过使用[FromHeader]上模特属性属性和[FromQuery]对模型本身的属性来糊弄模型绑定。 Such setup allows Swagger to correctly identify each header parameter.这种设置允许 Swagger 正确识别每个标头参数。

Controller endpoint sample:控制器端点示例:

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

HeadersParameters declaration: HeadersParameters声明:

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

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

I have created a custom attribute to avoid misunderstanding.我创建了一个自定义属性以避免误解。

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

So, final result is:所以,最后的结果是:

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

I understand this is a old post, but since there is not an accepted answer.我知道这是一篇旧帖子,但由于没有公认的答案。 This is also based on ASP.NET Core 6. You can combine multiple attributes Required, RegularExpression and FromHeader as shown below.这也是基于 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)

How this helps someone.这对某人有何帮助。

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

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