Пользовательское логическое связывание параметров

У меня есть метод WebApi, как этот:

public string Get([FromUri] SampleInput input)
{
    //do stuff with the input...
    return "ok";
}

Вход определяется следующим образом:

public class SampleInput
{
    // ...other fields
    public bool IsAwesome { get; set; }
}

Как бы то ни было, он работает нормально: если я передаю &isAwesome=true в строке запроса, параметр инициализируется значением true.

Моя проблема в том, что я хотел бы принимать значения &isAwesome=true и &isAwesome=1 как true. В настоящее время вторая версия приведет к тому, что IsAwesome будет false в модели ввода.


То, что я пробовал после прочтения различных сообщений в блоге по этому вопросу, заключалось в определении HttpParameterBinding:

public class BooleanNumericParameterBinding : HttpParameterBinding
{
    private static readonly HashSet<string> TrueValues =
        new HashSet<string>(new[] { "true", "1" }, StringComparer.InvariantCultureIgnoreCase);

    public BooleanNumericParameterBinding(HttpParameterDescriptor descriptor) : base(descriptor)
    {
    }

    public override Task ExecuteBindingAsync(
        ModelMetadataProvider metadataProvider, 
        HttpActionContext actionContext,
        CancellationToken cancellationToken)
    {
        var routeValues = actionContext.ControllerContext.RouteData.Values;

        var value = (routeValues[Descriptor.ParameterName] ?? 0).ToString();

        return Task.FromResult(TrueValues.Contains(value));
    }
}

... и зарегистрируйте его в Global.asax.cs, используя:

var pb = GlobalConfiguration.Configuration.ParameterBindingRules;
pb.Add(typeof(bool), p => new BooleanNumericParameterBinding(p));

и

var pb = GlobalConfiguration.Configuration.ParameterBindingRules;
pb.Insert(0, typeof(bool), p => new BooleanNumericParameterBinding(p));

Ничего из этого не получилось. Мой пользовательский HttpParameterBinding не вызывается, и я все еще получаю значение 1, переведенное на false.

Как настроить WebAPI для принятия значения 1 как true для Booleans?

Изменить: Представленный мной пример намеренно упрощен. У меня много моделей ввода в моем приложении, и они содержат много логических полей, которые я бы хотел обработать описанным выше способом. Если бы было только одно поле, я бы не стал прибегать к таким сложным механизмам.

Ответ 1

Похоже, что декорирование параметра с помощью FromUriAttribute просто полностью игнорирует правила привязки параметров. Я сделал простой тест, заменив входной параметр SampleInput простым bool:

public string Get([FromUri] bool IsAwesome)
{
    //do stuff with the input...
    return "ok";
}

и логическое правило по-прежнему не вызвано (IsAwesome приходит как null, когда вы вызываете &isAwesome=1). Как только вы удалите атрибут FromUri:

public string Get(bool IsAwesome)
{
    //do stuff with the input...
    return "ok";
}

правило вызывается и параметр правильно связан. Класс FromUriAttribute запечатан, поэтому я думаю, что вы сильно ввернуты - ну, вы всегда можете переопределить его и включить свою альтернативную логическую логику привязки ^ _ ^.