Я столкнулся с этим вопросом, желая узнать то же самое. Ниже приводится подробное описание моей ситуации и решения, которое я использовал (который использует другие ответы, представленные здесь). Первоначально я пытался использовать метод двух отдельных методов, но столкнулся с проблемой, когда сигнатуры методов этих методов стали идентичными.
У меня есть страница, на которой отображаются данные отчета. В верхней части страницы находится форма с некоторыми полями, которые позволяют пользователю указать параметры отчета, такие как дата начала, дата окончания и т. Д.
Первоначально я подошел к этому, создав два отдельных метода для обработки методов Get и Post. Метод post перенаправляет браузер на метод get, чтобы любые заданные параметры были добавлены в строку запроса и браузер не запрашивал у пользователя диалоговое окно с сообщением о том, что он собирается повторно отправить введенные данные. если они освежатся. Примечание. Позже я понял, что мог бы добиться этого, установив для атрибута метода моего элемента формы значение «Получить», но я думаю, что в идеале контроллер не должен знать, как реализовано представление, поэтому, на мой взгляд, это не имеет значения.
Когда я разработал эти два метода, я в конечном итоге оказался в ситуации, когда сигнатуры методов стали идентичными. Более того, мой код для этих двух методов стал почти идентичным, поэтому я решил объединить их в один метод и просто проверить глагол запроса, чтобы я мог сделать что-то немного отличающееся, когда запрос не является «Get». Дистиллированный пример моих двух методов показан ниже:
// this will not compile because the method signatures are the same
public ActionResult MyReport(DateRangeReportItem report)
{
// if there are no validation errors and the required report parameters are completed
if (ModelState.IsValid && report.ParametersAreComplete)
{
// retrieve report data and populate it on the report model
report.Result = GetReportData(report.CreateReportParameters());
}
return View(report);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyReport(DateRangeReportItem report)
{
if (ModelState.IsValid && report.ParametersAreComplete)
{
// redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
// this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
}
else
{
// there were validation errors, or the report parameters are not yet complete
return View(report);
}
}
Почему я принимаю объект модели в качестве параметра для моего метода get? Причина в том, что я хотел воспользоваться логикой проверки, уже встроенной в объект модели. Если кто-то переходит на мою страницу напрямую со всеми параметрами, уже указанными в строке запроса, я хочу продолжить, получить данные отчета и отобразить их на странице. Однако, если параметры, указанные в строке запроса, являются недопустимыми, я также хочу, чтобы ошибки проверки появлялись на странице. Поместив объект моей модели в качестве параметра, инфраструктура MVC автоматически попытается заполнить его и будет фиксировать любые ошибки валидации без какой-либо дополнительной работы с моей стороны.
Я использовал другие ответы на этот вопрос, чтобы создать свойство RequestHttpVerb для базового класса контроллера в моем проекте:
public HttpVerbs RequestHttpVerb
{
get { return (HttpVerbs)Enum.Parse(typeof(HttpVerbs), this.Request.HttpMethod, true); }
}
Итак, мой консолидированный метод выглядит следующим образом:
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult MyReport(DateRangeReportItem report)
{
// check if there are any validation errors in the model
// and whether all required report parameters have been completed
if (ModelState.IsValid && report.ParametersAreComplete)
{
// this is unnecessary if the form method is set to "Get"
// but within the controller I do not know for sure if that will be the case in the view
if (HttpVerbs.Get != this.RequestHttpVerb)
{
// redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
// this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
}
// there were no validation errors and all required report parameters are complete
// retrieve report data and populate that data on the model
report.Result = GetReportData(report.CreateReportParameters());
}
// display the view with the report object
// Any model state errors that occurred while populating the model will result in validation errors being displayed
return View(report);
}
Это мое текущее решение проблемы. Я бы предпочел не проверять свойство Request.HttpMethod, чтобы определить, нужно ли мне выполнять перенаправление, но я не нашел другого решения моей проблемы. Я был бы в порядке с сохранением двух отдельных методов для обработки запросов Get и Post, но идентичная сигнатура метода предотвратила это. Я бы предпочел переименовать мой метод-обработчик действия Post, чтобы избежать конфликта сигнатур метода и использовать какой-либо механизм, чтобы указать инфраструктуре MVC, что мой переименованный метод должен по-прежнему обрабатывать действие «MyReport», но я не знаю ни одного такого механизма в рамках MVC.