Значения по умолчанию ASP.NET MVC QueryString, переопределяющие предоставленные значения?

Попробуйте это пожалуйста.

ThisWorkbook.Saved = True
Application.Quit
25
задан Greg Beech 19 January 2009 в 16:49
поделиться

4 ответа

Лучший способ взглянуть на 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

Надеюсь, что это помогает прояснить некоторые вещи.

30
ответ дан Dale Ragan 15 October 2019 в 16:28
поделиться

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

Работы как очарование!

15
ответ дан Greg Beech 15 October 2019 в 16:28
поделиться

Я думал, что точка с Маршрутизацией в MVC должна избавиться от querystrings. Как это:

routes.MapRoute(
    "test",
    "Test/Foo/{x}",
    new { controller = "Test", action = "Foo", x = 1 });
-3
ответ дан Spoike 15 October 2019 в 16:28
поделиться

Я думаю, что причина, по которой параметры строки запроса не переопределяют значения по умолчанию, заключается в том, чтобы не дать людям взломать URL.

Кто-то может использовать URL-адрес, строка запроса которого содержит контроллер, действие или другие значения по умолчанию, которые вы не хотели, чтобы они меняли.

Я справился с этой проблемой, выполнив то, что предложил @ Dale-Ragan, и применил ее в методе действий. Работает для меня.

0
ответ дан Richard Garside 15 October 2019 в 16:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: