David Klempfner
David Klempfner

Reputation: 9930

Return error msg in payload when header not present

I have this action method:

[HttpGet]
public virtual async Task<IActionResult> GetModifiedSince([HeaderCompanyId] Guid? xCompanyId)
{
...
}

The HeaderCompanyId class in the above action method is defined here:

public class HeaderCompanyIdAttribute : FromHeaderAttribute
{
    public HeaderCompanyIdAttribute()
    {
        Name = "x-company-id";
    }
}

I'm using this IOperationFilter to make the xCompanyId required:

public class AddSwaggerToStandardHeadersFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        var companyIdHeader = operation.Parameters.FirstOrDefault(x => x.Name == "x-company-id");
        if (companyIdHeader != null)
        {
            companyIdHeader.Description = "Company id";
            companyIdHeader.Required = true;
        }
    }
}

This is where I add the OperationFilter:

public static IServiceCollection RegisterSwagger(this IServiceCollection services) =>
    services.AddSwaggerGen(setupAction =>
    {
        ...
        setupAction.OperationFilter<AddSwaggerToStandardHeadersFilter>();
    }
}

I can see the header marked as mandatory in the Swagger UI. But when I hit the endpoint with no value for the xCompanyId the ModelState.IsValid = true and I get no error msg back about the header being required.

How can I return a 4XX to indicate that the xCompanyId header is needed? Ideally if I put a breakpoint in the action method, it shouldn't even get hit.

Upvotes: 1

Views: 152

Answers (3)

Serhii Matvienko
Serhii Matvienko

Reputation: 312

Also, you can try to use a Model instead of 'Guid' parameter

[HttpGet]
public virtual async Task<IActionResult> GetModifiedSince([FromHeader]YourCustomHeader headers)
{
 ...
}

use your custom model

public class YourCustomHeader
{
    [Required]
    public string xCompanyId { get; set; }
}

Upvotes: 1

Elendil Zheng-MSFT
Elendil Zheng-MSFT

Reputation: 541

You can add your validation in the request pipe line as below in Startup.cs Config part.

app.Use(async(context,next)=>{
                var companyHeader=context.Request.Headers["xCompanyId"];
                if(companyHeader==null)
                {
                  context.Response.StatusCode=400;//Bad request if no companyHeader
                  await context.Response.CompleteAsync();
                }
                else{
                await next.Invoke();}
            });

Upvotes: 0

Serhii Matvienko
Serhii Matvienko

Reputation: 312

What about doing a simple check in the API method:

 if (xCompanyId == null)
  return BadRequest("CompanyId is mandatory");

Upvotes: 0

Related Questions