Один из моих коллег нашел ссылку, которая указывает на то, что это было задумано , и кажется, что автор этой статьи поднял проблему с командой MVC , сказав, что это было изменение по сравнению с более ранние выпуски. Ответ от них был ниже (для «страницы» вы можете прочитать «х», чтобы он имел отношение к вопросу выше):
Это по замыслу. Маршрутизация не
займитесь строкой запроса
ценности; это касается только
значения из RouteData. Вам следует
вместо этого удалите запись для "страницы"
из словаря по умолчанию, и в
либо сам метод действия или в
фильтр устанавливает значение по умолчанию для
"страница", если она еще не установлена.
Мы надеемся, что в будущем
более простой способ пометить параметр как
явно из RouteData,
Строка запроса или форма. Пока это
Реализованное выше решение должно
Работа. Пожалуйста, дайте нам знать, если это
нет!
Итак, похоже, что это «правильное» поведение, однако оно настолько ортогонально принципу наименьшего удивления , что я до сих пор не могу в это поверить.
Редактирование # 1: обратите внимание, что в сообщении описан метод предоставления значений по умолчанию, однако он больше не работает, поскольку свойство ActionMethod
, которое он использует для доступа к MethodInfo
, было удалено в последней версии ASP. NET MVC. В настоящее время я работаю над альтернативой и опубликую ее, когда все будет готово.
Редактирование # 2: я обновил идею в связанном посте, чтобы она работала с выпуском Preview 5 ASP.NET MVC, и я верю, что он должен работать и с бета-версией, хотя я не могу гарантировать это, поскольку у нас нет еще не перешел на этот релиз. Это так просто, что я только что разместил это здесь.
Сначала есть атрибут по умолчанию (мы не можем использовать существующий .NET DefaultValueAttribute
, поскольку он должен наследоваться от CustomModelBinderAttribute
):
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class DefaultAttribute : CustomModelBinderAttribute
{
private readonly object value;
public DefaultAttribute(object value)
{
this.value = value;
}
public DefaultAttribute(string value, Type conversionType)
{
this.value = Convert.ChangeType(value, conversionType);
}
public override IModelBinder GetBinder()
{
return new DefaultValueModelBinder(this.value);
}
}
Пользовательское связующее:
public sealed class DefaultValueModelBinder : IModelBinder
{
private readonly object value;
public DefaultValueModelBinder(object value)
{
this.value = value;
}
public ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
var request = bindingContext.HttpContext.Request;
var queryValue = request .QueryString[bindingContext.ModelName];
return string.IsNullOrEmpty(queryValue)
? new ModelBinderResult(this.value)
: new DefaultModelBinder().BindModel(bindingContext);
}
}
И затем вы можете просто применить его к параметрам метода, которые входят в строку запроса, например,
public ActionResult Foo([Default(1)] int x)
{
// implementation
}
Работает как шарм!