问题描述
我有这种怪异的行为,当我在Swagger UI(和其他API客户端)中设置自定义标头参数时,调用只是挂起并且永远不会返回,请求没有记录(我正在用DelegatHandler记录),也没有我在浏览器或API客户端(尝试过Postman)中得到响应。
我尝试了多种添加方式。最初,我将其作为方法的参数,只是更改了名称:
Get(int id,[FromHeader("X-Request-ID")] Guid? x_Request_ID = null)
FromHeaderAttribute实现:
public class FromHeaderAttribute : P@R_502_6460@meterBindingAttribute
{
public virtual string Name { get; set; }
public override HttpP@R_502_6460@meterBinding GetBinding(HttpP@R_502_6460@meterDescriptor p@R_502_6460@meter)
{
return new FromHeaderBinding(p@R_502_6460@meter,p@R_502[email protected]@R_502_6460@meterName);
}
}
public class FromHeaderBinding : HttpP@R_502_6460@meterBinding
{
private readonly string _name;
public FromHeaderBinding(HttpP@R_502_6460@meterDescriptor p@R_502_6460@meter,string headerName)
: base(p@R_502_6460@meter)
{
if (string.IsNullOrEmpty(headerName))
{
throw new ArgumentNullException("headerName");
}
_name = headerName;
}
public override Task ExecuteBindingAsync(ModelMetadataProvider MetadataProvider,HttpActionContext actionContext,CancellationToken cancellationToken)
{
if (actionContext.Request.Headers.TryGetValues(_name,out var values))
{
var converter = TypeDescriptor.GetConverter(Descriptor.P@R_502_6460@meterType);
try
{
actionContext.ActionArguments[Descriptor.P@R_502_6460@meterName] = converter.ConvertFromString(values.FirstOrDefault());
}
catch (Exception exception)
{
var error = new HttpError("The request is invalid.") { MessageDetail = exception.Message };
throw new HttpResponseException(actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest,error));
}
}
else if (Descriptor.IsOptional)
{
actionContext.ActionArguments[Descriptor.P@R_502_6460@meterName] = Descriptor.DefaultValue;
}
else
{
var error = new HttpError("The request is invalid.") { MessageDetail = $"The `{_name}` header is required." };
throw new HttpResponseException(actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest,error));
}
return Task.Fromresult<object>(null);
}
}
var headerP@R_502_6460@meters = apiDescription.P@R_502_6460@meterDescriptions
.Where(p => p.P@R_502[email protected]@R_502_6460@meterBinderAttribute is FromHeaderAttribute);
if (headerP@R_502[email protected]())
{
if (operation.p@R_502_6460@meters == null)
{
operation.p@R_502_6460@meters = new List<P@R_502_6460@meter>();
}
var temp = headerP@R_502[email protected](operation.p@R_502_6460@meters ?? new List<P@R_502_6460@meter>(),p1 => p1.Name,p2 => p2.name,(p1,p2) => new
{
p@R_502_6460@meterBinding = p1.P@R_502[email protected]@R_502_6460@meterBinderAttribute as FromHeaderAttribute,p@R_502_6460@mterDescription = p1,operationP@R_502_6460@meter = p2
})
.ToList();
temp.ForEach(p =>
{
p.operationP@R_502[email protected](p.operationP@R_502_6460@meter);
operation.p@R_502[email protected](new P@R_502_6460@meter
{
name = p.p@R_502[email protected],@in = "header",description = p.operationP@R_502[email protected],type = p.operationP@R_502[email protected],required = p.operationP@R_502_6460@meter.required,format = p.operationP@R_502[email protected]
});
});
}
后来我将最后一部分更改为简单:
p.operationP@R_502[email protected] = p.p@R_502[email protected];
p.operationP@R_502_6460@meter.@in = "header";
问题是,无论何时传递了无效的GUID(uuid v4),调用都被挂起,从未返回,并且在我的代码中未记录任何内容,但是IIS日志显示该请求以预期的结果传递了。调试时,我的代码也没有在ExecuteBindingAsync中中断。
如果Guid格式正确,则一切正常。
我发现改名是(最有可能的)主要问题,当测试除改名外的所有内容都相同时,即只是过滤器而已:
p.operationP@R_502_6460@meter.@in = "header";
每次都能很好地工作,但是Swagger中的标头是x_Request_ID
。我以为名称更改是问题所在,因此为了进行测试,创建了一个简单的方法,在其中我刚刚添加了一个新参数:
if (operation.operationId == "API_Get2")
{
operation.p@R_502[email protected](new P@R_502_6460@meter
{
name = "X-Request-ID",description = "Request ID",type = "string",required = false
format = "uuid"
});
}
,并将操作的签名更改为:
Get(int id)
但是,无论它是有效还是无效的GUID,它每次都挂起。
我一直在试图找出原因,以及如何正确地以大张旗鼓显示自定义标头,并使代码正常解析两天,而且没有运气。我还尝试了ModelBinding,但是在那种情况下,标题只是被忽略了。
对我来说,如果标头是操作的参数,还是不一样,我只是希望它能以准确的说明显示出来。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)