WebApi: ApiExplorer и пользовательские привязки моделей

Большинство моих маршрутов API сегментированы следующим образом:

/api/{segment}/MyEntity (например, "/api/SegmentA/MyEntity")

Где я определил ModelBinder, который преобразует строку в объект Segment следующим образом:

class SegmentModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (value == null || String.IsNullOrEmpty(value.AttemptedValue))
            return false;

        bindingContext.Model = **logic to find segment object from value.AttemptedValue**;
        return true;
    }
}

Настроен как:

GlobalConfiguration.Configuration.BindParameter(typeof(Segment), new SegmentModelBinder());

Итак, мои маршруты в конечном итоге выглядят так:

public class MyEntityController : BaseController
{
    [HttpGet, Route("api/{segment}/MyEntity")]
    public IEnumerable<MyEntity> Get(Segment segment)
    {
        ...
    }
}

Проблема в том, что сейчас я пытаюсь создать документацию для этих вызовов API, а ApiExplorer полностью запутался в этих маршрутах и ​​игнорирует их.

Как мне сказать ему, что для этих маршрутов, когда он видит параметр типа Segment, это действительно просто строка из маршрута?


person John    schedule 05.06.2015    source источник


Ответы (1)


Переключение с использования ModelBinder на TypeConverter решило проблему:

[TypeConverter(typeof(MyEntityConverter))]
public class MyEntity
{....

-

public class MyEntityConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;
        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        var key = value as string;
        if (!String.IsNullOrEmpty(key))
            return **Find Entity**;

        return base.ConvertFrom(context, culture, value);
    }
}

Редактировать:

Если вы когда-нибудь вернете этот объект при вызове, он вам также понадобится, иначе сериализатор newtonsoft json сериализует класс в имя типа:

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return false;
    }
person John    schedule 05.06.2015