Публичный метод для каждого представления?ActionResult и маршруты по умолчанию в ASP.MVC

StackOverflow https://stackoverflow.com/questions/671561

  •  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);
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top