Публичный метод для каждого представления?ActionResult и маршруты по умолчанию в ASP.MVC
-
21-08-2019 - |
Вопрос
Я экспериментирую с ASP.NET MVC и маршрутами.
Похоже, что MVC заставляет меня добавлять общедоступный метод к контроллеру каждый раз, когда я хочу создать представление.Например:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
//... a public method for every view.. :(
}
Я не хочу создавать общедоступный метод для каждого представления.По умолчанию я хочу, чтобы поведение «return View()» было для всех представлений в системе, если не указано иное.
Например, HTTP GET:
site.com/about site.com/features site.com/ site.com/testimonials site.com/contact-us
В нынешнем виде мне бы хотелось добавить:
HomeController.About()
HomeController.Features()
HomeController.Index()
HomeController.Testimonials()
HomeController.ContactUs()
Все приводят к возврату View().Это моя проблема, я пытаюсь исключить создание методов публичных действий для простых представлений.
Для представлений, требующих дополнительной обработки, например страницы «Связаться с нами» в HTTP POST, можно:
site.com/contact-us
Я хотел бы специально добавить в контроллер метод для отправки SMTP-сообщения.
Ниже приведен более краткий пример того, что я пытаюсь сделать:
public class HomeController{
public ActionResult ShowBasicView(){
//HTTP GET:
//site.com/about
//site.com/features
//site.com/
//site.com/testimonials
//All URLs above map to this action
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ContactUs(FormCollection data){
//HTTP POST:
//site.com/contact-us
//POST URL maps here.
SmtpClient.Send(new MailMessage()) //etc...
return View()
}
}
Спасибо, Брайан
Решение
Потенциальная проблема с использованием ShowBasicView в вашем редактировании заключается в том, что из-за неявной связи представлений каждый из этих URL-адресов будет возвращать одно и то же представление, а именно:
\Views\Home\ShowBasicView.aspx
Возможно, это именно то, что вам нужно, хотя это маловероятно.
Вы могли бы настроить это, имея такой маршрут, как:
routes.MapRoute(
"ShowBasic",
"{id}",
new { controller = "Home", action = "ShowBasicView", id = "home" }
);
И измените свой контроллер так:
public class HomeController: Controller{
public ActionResult ShowBasicView(string pageName){
// Do something here to get the page data from the Model,
// and pass it into the ViewData
ViewData.Model = GetContent(pageName);
// All URLs above map to this action
return View();
}
}
В качестве альтернативы, если контент жестко запрограммирован в представлениях, вы можете попробовать:
public class HomeController: Controller{
public ActionResult ShowBasicView(string pageName){
// All URLs above map to this action
// Pass the page name to the view method to call that view.
return View(pageName);
}
}
Возможно, вам также придется добавить маршрут для базового URL-адреса, поскольку маршрут ShowBasic будет работать только с URL-адресом со строковым значением.
Другие советы
Вы можете добавить следующий метод в свой контроллер, он
protected override void HandleUnknownAction(string actionName)
{
try{
this.View(actionName).ExecuteResult(this.ControllerContext);
}catch(Exception ex){
// log exception...
base.HandleUnknownAction(actionName);
}
}