Как я могу перегрузить действия ASP.NET MVC на основе принятых HTTP-глаголов? - PullRequest
23 голосов
/ 14 июня 2011

Хотел использовать тот же URL-адрес для GET / PUT / DELETE / POST для API на основе REST, но когда единственное, что отличается в действиях, это какие HTTP-глаголы он принимает, он считает их дублирующимися!

«Тип уже определяет член с именем« Index »с такими же типами параметров.»

На что я сказал, и что?Этот принимает только GET, этот принимает только POST ... должен быть в состоянии сосуществовать правильно?

Как?

Ответы [ 4 ]

35 голосов
/ 14 июня 2011

Это не ограничение ASP.NET MVC или что-то еще.Это .NET и то, как работают классы: как бы вы ни старались, у вас не может быть двух методов с одинаковыми именами в одном классе, которые принимают одинаковые параметры.Вы можете обмануть, используя атрибут [ActionName]:

[HttpGet]
[ActionName("Foo")]
public ActionResult GetMe()
{
   ...
}

[HttpPut]
[ActionName("Foo")]
public ActionResult PutMe()
{
   ...
}

[HttpDelete]
[ActionName("Foo")]
public ActionResult DeleteMe()
{
   ...
}

[HttpPost]
[ActionName("Foo")]
public ActionResult PostMe()
{
   ...
}

Конечно, в реальном приложении RESTFul разные глаголы также принимают разные параметры, поэтому у вас редко будут такие ситуации.

Вы можете взглянуть на SimplyRestful , чтобы узнать, как организовать ваши маршруты.

8 голосов
/ 14 июня 2011

В то время как ASP.NET MVC позволит вам иметь два действия с одним и тем же именем, .NET не позволит вам иметь два метода с одинаковой сигнатурой - то есть с одинаковым именем и параметрами.

Вам нужно будет по-разному называть методы, используя атрибут ActionName, чтобы сообщить ASP.NET MVC, что на самом деле это одно и то же действие.

Тем не менее, если вы говорите о GET и POST, эта проблема, скорее всего, исчезнет, ​​поскольку действие POST будет принимать больше параметров, чем GET, и, следовательно, будет различимым.

Итак, вам нужно:

[HttpGet]
public ActionResult ActionName() {...}

[HttpPost, ActionName("ActionName")]
public ActionResult ActionNamePost() {...}

Или:

[HttpGet]
public ActionResult ActionName() {...}

[HttpPost]
public ActionResult ActionName(string aParameter) {...}
1 голос
/ 04 июня 2012

Другой вариант - иметь единственный метод, который принимает все и различает HttpMethod и вызывает соответствующий код оттуда.Например,

            string httpMethod = Request.HttpMethod.ToUpperInvariant();

            switch (httpMethod)
            {
                case "GET":
                    return GetResponse();

                case "POST":
                    return PostResponse();

                default:
                    throw new ApplicationException(string.Format("Unsupported HttpMethod {0}.", httpMethod));
            }
0 голосов
/ 23 января 2013

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...