在Swagger上为.net Web API调用添加自定义标头字段的最佳做法是什么?

时间:2018-08-17 15:03:39

标签: c# asp.net-web-api http-headers swagger swagger-ui

我可以看到很多在线方法,但其中大多数都是凌乱的,对我而言,我使用的是这两种方法

  • 使用范围,我为移动设备做了一个,为网站做了另一个

    var webScope = apiDescription.ActionDescriptor.GetFilterPipeline()
       .Select(filterInfo => filterInfo.Instance)
       .OfType<WebAuthorize>()
       .SelectMany(attr => attr.Roles.Split(','))
       .Distinct();
    
    var mobileScope = apiDescription.ActionDescriptor.GetFilterPipeline()
        .Select(filterInfo => filterInfo.Instance)
        .OfType<MobileAuthorize>()
       .SelectMany(attr => attr.Roles.Split(','))
       .Distinct();
    

    之所以起作用,是因为我有两种不同的方式来授权api调用,如您所见,我拥有移动授权和网络授权,因此我的api调用看起来像这样:

    [HttpGet]
    [Route("something")]
    [WebAuthorize(Code = PermissionCode, Type =PermissionType)]
    public async Task<Dto> Getsomething()
    {
        return await unitOfWork.GetService<ISomething>().GetSomething();
    }
    

    使用范围时遇到的问题是,所有具有网络授权的调用都将共享相同的标头,因此对于特殊调用,我使用了另一种添加自定义标头的方式。

  • 使用apiDescription.RelativePath,我将检查它是否相对路径等于我要添加该自定义标头的api调用,例如:

    [HttpPost]
    [Route("rename")]
    [InHouseAuthorize(Code = PermissionCode, Type =PermissionType)]
    public async Task<HttpResponseMessage> RenameDevice()
    {
        HttpRequestMessage request = Request ?? new HttpRequestMessage();
        String deviceName = request.Headers.GetValues("deviceName").FirstOrDefault();
        String deviceGuid = request.Headers.GetValues("deviceGuid").FirstOrDefault();
        await unitOfWork.GetService<IDeviceService>().RenameDevice(deviceGuid, deviceName);
        await unitOfWork.Commit();
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
    

    然后我将以下内容添加到AddRequiredHeaderParameter.cs中

        if (apiDescription.RelativePath.Contains("device/rename"))
        {
            operation.parameters.Add(new Parameter
            {
                name = "deviceGuid",
                @in = "header",
                description = "Add the Device Guid",
                type = "string",
                required = false
            });
            operation.parameters.Add(new Parameter
            {
                name = "DeviceName",
                @in = "header",
                description = "Add the Device Name",
                type = "string",
                required = false
            });
        }
    

    起初这很方便且足够好修复,但是事情变得很难看,因为我添加了许多需要自定义标头的调用,并且如果相同的URL具有Get和Post,那么它甚至会变得更丑。

我正在寻找解决此问题的最佳方法。

1 个答案:

答案 0 :(得分:1)

可以将[F​​romHeader]属性用于应在自定义标头中发送的网络方法参数(或Model类中的属性)。像这样:

[HttpGet]
public ActionResult Products([FromHeader(Name = "User-Identity")]string userIdentity)

对我来说,这似乎是最简单的解决方案。至少对于ASP.NET Core 2.1和Swashbuckle.AspNetCore 2.5.0来说,它可以正常工作。