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

У меня есть метод 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));
 }
}
</string></string>

... и зарегистрируйте его в 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 запечатан, поэтому я думаю, что вы сильно ввернуты - ну, вы всегда можете переопределить его и включить свою альтернативную логическую логику привязки ^ _ ^.

licensed under cc by-sa 3.0 with attribution.