Как работают атрибуты httppost, httpput и т. Д. В ASP.NET MVC 2? - PullRequest
6 голосов
/ 16 апреля 2010

В ASP.NET MVC 2 пара новых атрибутов фильтра действий была введена как «сокращение» для атрибутов в ASP.NET MVC 1; например, применение HttpPostAttribute делает то же самое, что применение [AcceptVerbs(HttpVerbs.Post)] к методу действия.

Кроме того, с более подробным синтаксисом можно комбинировать различные методы, например, для Post и Delete.

.

Теперь мне интересно: как работают новые атрибуты? Если я применяю [HttpPost] и [HttpDelete], будет ли ASP.NET MVC 2 разрешать оба или требует оба (таким образом, ничего не разрешать)?

Ответы [ 4 ]

5 голосов
/ 16 апреля 2010

Глядя на код для ActionMethodSelector, выясняется, что все атрибуты метода действия должны возвращать true для IsValidForRequest, прежде чем это действие будет добавлено в набор возможных подходящих методов. Поскольку HttpPost и HttpDelete не могут возвратить IsValidForRequest для одного и того же запроса, я ожидаю, что использование обоих этих методов не позволит этому действию когда-либо соответствовать любому запросу.

Вот заметный комментарий из кода:

приватный статический список RunSelectionFilters (...) {
// удаляем все методы, которые отказываются от этого запроса
// чтобы отказаться, хотя бы один атрибут, определенный в методе, должен вернуть false

(акцент мой)

Обратите внимание, что вы все равно можете использовать AcceptVerbs и явно ИЛИ глаголы, если вам нужно совпадать с любым из них.

РЕДАКТИРОВАТЬ - вот вам атрибут HttpPostOrDelete.

[AttributeUsage( AttributeTargets.Method, AllowMultiple = false, Inherited = false )]
public class HttpPostOrDeleteAttribute : ActionMethodSelectorAttribute
{
    private static readonly AcceptVerbsAttribute _innerPostAttribute = new AcceptVerbsAttribute( HttpVerbs.Post );
    private static readonly AcceptVerbsAttribute _innerDeleteAttribute = new AcceptVerbsAttribute( HttpVerbs.Delete );

    public override bool IsValidForRequest( ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo )
    {
        return _innerDeleteAttribute.IsValidForRequest( controllerContext, methodInfo )
               || _innerPostAttribute.IsValidForRequest( controllerContext, methodInfo );
    }
}
4 голосов
/ 16 апреля 2010

Все фильтры в MVC - без исключения - независимы друг от друга. Никакой фильтр в специальном корпусе MVC отсутствует. Это было намеренное проектное решение, чтобы компоненты инфраструктуры MVC, такие как invoker, не могли «обманывать» и обрабатывать фильтры, расположенные в двоичном файле MVC, иначе, чем фильтры, которые вы, как разработчик приложения, написали бы.

Таким образом, когда вызывающий видит [HttpGet] и [HttpPost] в одном и том же методе, не существует специального кода для объединения двух. Они выполняются независимо. И поскольку они никогда не могут вернуть true для одного и того же запроса, [HttpGet, HttpPost] фактически исключает любой конкретный метод из метода действия.

3 голосов
/ 23 октября 2010

Вы можете использовать AcceptVerbs для создания цепочки, например:

[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]
public ActionResult Customers() {
}

или

[AcceptVerbs("GET","POST")]
public ActionResult Customers() {
}
0 голосов
/ 16 апреля 2010

Если вы сложите [HttpPost] и [HttpDelete] вместе, я думаю, что потребуются оба (что невозможно). Если вы включите [HttpGet], это тоже не сработает, и т.д ...

Вы можете легко проверить это, просто взяв существующий метод действия [HttpPost] и добавив к нему [HttpDelete]. Пост перестанет работать.

Я не нашел ни одного примера, где мне нужно было бы связать их, как вы предлагаете.

...