ApiExplorer does not recognize route attributes with custom type

前端 未结 2 1332
离开以前
离开以前 2021-01-24 18:37

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 displ

相关标签:
2条回答
  • 2021-01-24 19:22

    You need to:

    1. add HttpParameterBinding for your IntegerListParameter type
    2. mark the binding as IValueProviderParameterBinding and implement ValueProviderFactories
    3. add a converter for IntegerListParameter and override CanConvertFrom method for typeof(string) parameter

    After these actions, route with custom type IntegerListParameter must be recognized in ApiExplorer.

    See my example for type 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);
        }
    }
    
    0 讨论(0)
  • 2021-01-24 19:41

    Not exactly sure what data structure IntegerListParameter list is but if you need to send a comma delimited list of integers in the query(e.g. ~api/products?ids=1,2,3,4) you can use filter attributes. An example implementation of this can be found here: Convert custom action filter for Web API use?

    0 讨论(0)
提交回复
热议问题