Подтвердить что ты не робот

Как я могу перегрузить ASP.NET MVC Actions на основе принятых HTTP-глаголов?

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

"Тип уже определяет член с именем" Index "с теми же параметрами."

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

Как?

4b9b3361

Ответ 1

Это не ограничение 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 для некоторых идей о том, как ваши маршруты могут быть организованы.

Ответ 2

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

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

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

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

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

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

Или:

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

[HttpPost]
public ActionResult ActionName(string aParameter) {...}

Ответ 3

Другой вариант - иметь единственный метод, который принимает все и различает 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));
            }

Ответ 4

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

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