ApiExplorer无法识别具有自定义类型的路由属性 [英] ApiExplorer does not recognize route attributes with custom type
问题描述
我有一个项目,我想在其中使用具有自定义类型的路由属性. 我将自定义类型用作查询参数的以下代码可以正常工作,并且帮助页面显示该自定义类型.
I have a project where I want to use route attributes with a custom type. The following code where I have the custom type as a query parameter works fine and the help page displays the custom type.
// GET api/values?5,6
[Route("api/values")]
public string Get(IntegerListParameter ids)
{
return "value";
}
WebApi.HelpPage提供以下文档 帮助:页面
WebApi.HelpPage gives the following documentation Help:Page
如果我更改代码以使用路由属性,结果是我得到一个空的帮助页面.
If I change the code to use route attributes, the result is that I get an empty help page.
// GET api/values/5,6
[Route("api/values/{ids}")]
public string Get(IntegerListParameter ids)
{
return "value";
}
当我检查在HelpController.cs中观察到的代码时,ApiExplorer.ApiDescriptions返回一个空的ApiDescriptions集合
When I inspect the code I observe in HelpController.cs that ApiExplorer.ApiDescriptions returns an empty collection of ApiDescriptions
public ActionResult Index()
{
ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider();
Collection<ApiDescription> apiDescriptions = Configuration.Services.GetApiExplorer().ApiDescriptions;
return View(apiDescriptions);
}
有什么办法让ApiExplorer将我的自定义类IntegerListParameter识别为属性路由?
Is there any way to get ApiExplorer to recognize my custom class IntegerListParameter as attribute routing?
推荐答案
您需要:
- 为您的
IntegerListParameter
类型添加HttpParameterBinding - 将绑定标记为
IValueProviderParameterBinding
并实现ValueProviderFactories
- 为
IntegerListParameter
添加一个转换器,并为typeof(string)
参数覆盖CanConvertFrom
方法
- add HttpParameterBinding for your
IntegerListParameter
type - mark the binding as
IValueProviderParameterBinding
and implementValueProviderFactories
- add a converter for
IntegerListParameter
and overrideCanConvertFrom
method fortypeof(string)
parameter
执行这些操作后,必须在ApiExplorer中识别具有自定义类型IntegerListParameter的路由.
After these actions, route with custom type IntegerListParameter must be recognized in ApiExplorer.
请参阅示例ObjectId
的示例:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//...
config.ParameterBindingRules.Insert(0, GetCustomParameterBinding);
TypeDescriptor.AddAttributes(typeof(ObjectId), new TypeConverterAttribute(typeof(ObjectIdConverter)));
//...
}
public static HttpParameterBinding GetCustomParameterBinding(HttpParameterDescriptor descriptor)
{
if (descriptor.ParameterType == typeof(ObjectId))
{
return new ObjectIdParameterBinding(descriptor);
}
// any other types, let the default parameter binding handle
return null;
}
}
public class ObjectIdParameterBinding : HttpParameterBinding, IValueProviderParameterBinding
{
public ObjectIdParameterBinding(HttpParameterDescriptor desc)
: base(desc)
{
}
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
{
try
{
SetValue(actionContext, new ObjectId(actionContext.ControllerContext.RouteData.Values[Descriptor.ParameterName] as string));
return Task.CompletedTask;
}
catch (FormatException)
{
throw new BadRequestException("Invalid id format");
}
}
public IEnumerable<ValueProviderFactory> ValueProviderFactories { get; } = new[] { new QueryStringValueProviderFactory() };
}
public class ObjectIdConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
}
这篇关于ApiExplorer无法识别具有自定义类型的路由属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!