Попробуйте это пожалуйста.
ThisWorkbook.Saved = True
Application.Quit
Лучший способ взглянуть на ASP.NET MVC с QueryStrings - это воспринимать их как значения, о которых маршрут не знает. Как вы узнали, QueryString не является частью RouteData, поэтому вы должны хранить то, что вы передаете, в виде строки запроса отдельно от значений маршрута.
Способ обойти их - создать значения по умолчанию самостоятельно в действии, если значения, переданные из QueryString, равны нулю.
В вашем примере маршрут знает о x, поэтому ваш URL должен действительно выглядеть так:
/Test/Foo or /Test/Foo/5
и маршрут должен выглядеть так:
routes.MapRoute("test", "Test/Foo/{x}", new {controller = "Test", action = "Foo", x = 1});
Чтобы получить поведение, которое вы искали.
Если вы хотите передать значение QueryString, скажем, как номер страницы, вы должны сделать это:
/Test/Foo/5?page=1
И ваше действие должно измениться следующим образом:
public ActionResult Foo(int x, int? page)
{
Trace.WriteLine(x);
Trace.WriteLine(page.HasValue ? page.Value : 1);
return new EmptyResult();
}
Сейчас тест:
Url: /Test/Foo Trace: 1 1 Url: /Test/Foo/5 Trace: 5 1 Url: /Test/Foo/5?page=2 Trace: 5 2 Url: /Test/Foo?page=2 Trace: 1 2
Надеюсь, что это помогает прояснить некоторые вещи.
Один из моих коллег нашел ссылка, которая указывает, что это дизайном , и кажется, что автор той статьи поднял вопрос с командой MVC высказывание, что это было изменением от более ранних выпусков. Ответ от них был ниже (для "страницы", которую можно прочитать, "x" для имения его касаются вопроса выше):
Это дизайном. Маршрутизация не интересуется значениями строки запроса; это интересуется только значениями от RouteData. Необходимо вместо этого удалить запись для "страницы" из словаря Значений по умолчанию, и или в самом методе действия или в фильтре устанавливает значение по умолчанию для "страницы", если это не было уже установлено.
Мы надеемся в будущем, имеют более легкий способ отметить параметр как явно прибывающий из RouteData, строки запроса или формы. Пока это не реализовано, вышеупомянутое решение должно работать. Сообщите нам, не делает ли это!
, Таким образом, кажется, что это поведение 'корректно', однако это столь ортогонально к принцип наименьшего количества удивления , что я все еще не могу вполне верить ему.
<час> Редактирование № 1: Обратите внимание, что сообщение подробно излагает метод того, как обеспечить значения по умолчанию, однако это больше не работает ActionMethod
свойство, которое он использует для доступа эти MethodInfo
, был удален в последней версии ASP.NET MVC. Я в настоящее время работаю над альтернативой и отправлю ее, когда сделано.
Редактирование № 2: я обновил идею в связанном сообщении для работы с Предварительным просмотром 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);
}
}
И затем можно просто применить его к параметрам метода, которые входят на querystring, например,
public ActionResult Foo([Default(1)] int x)
{
// implementation
}
Работы как очарование!
Я думал, что точка с Маршрутизацией в MVC должна избавиться от querystrings. Как это:
routes.MapRoute(
"test",
"Test/Foo/{x}",
new { controller = "Test", action = "Foo", x = 1 });
Я думаю, что причина, по которой параметры строки запроса не переопределяют значения по умолчанию, заключается в том, чтобы не дать людям взломать URL.
Кто-то может использовать URL-адрес, строка запроса которого содержит контроллер, действие или другие значения по умолчанию, которые вы не хотели, чтобы они меняли.
Я справился с этой проблемой, выполнив то, что предложил @ Dale-Ragan, и применил ее в методе действий. Работает для меня.