Método público para cada ponto de vista? Padrão ActionResult e Rotas em ASP.MVC

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

  •  21-08-2019
  •  | 
  •  

Pergunta

Eu estou experimentando com ASP.NET MVC e Rotas.

Parece MVC me obriga a adicionar um método público para o controlador qualquer momento eu quero criar uma visão. Por exemplo:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        return View();
    }

    //... a public method for every view.. :(
}

Eu não quero criar um método público para cada vista. Por padrão, quero que o comportamento de "retorno View ()" para todos os pontos de vista do sistema, a menos que especificado em contrário.

Por exemplo, HTTP GET:

site.com/about
site.com/features
site.com/
site.com/testimonials
site.com/contact-us

Tal como está agora, eu teria que adicionar:

HomeController.About()
HomeController.Features()
HomeController.Index()
HomeController.Testimonials()
HomeController.ContactUs()

Todos os resultado em "return View ()". Este é o meu problema, eu estou tentando eliminar a criação de métodos de ação pública para vistas simples.

Para vistas que requerem processamento adicional, como uma página Fale Conosco sobre um HTTP POST para:

site.com/contact-us

Eu gostaria de adicionar especificamente um método no controlador para enviar uma mensagem SMTP.


A seguir é um exemplo mais conciso do que estou tentando fazer:

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()
   }

}

Obrigado, Brian

Foi útil?

Solução

O problema potencial com ter a ShowBasicView de sua edição é que, devido à fiação implícita de pontos de vista, cada um desses urls tudo vai voltar ao mesmo ponto de vista, a saber:

\ Views \ Home \ ShowBasicView.aspx

Agora, isso pode ser o que quiser, embora seja pouco provável.

Você poderia configurar isso por ter uma rota tais como:

routes.MapRoute(  
  "ShowBasic",
  "{id}",
  new { controller = "Home", action = "ShowBasicView", id = "home" }
);

e modificar seu controlador para:

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();
  }
}

Como alternativa, se o conteúdo é codificado nas vistas você pode tentar:

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);
  }
}

Você vai, possivelmente, também tem que adicionar uma rota para o URL base, como a rota ShowBasic só vai bater para uma URL com um valor de string.

Outras dicas

Você pode adicionar seguinte método em seu controlador, ele

protected override void HandleUnknownAction(string actionName)
{
    try{
       this.View(actionName).ExecuteResult(this.ControllerContext);
    }catch(Exception ex){
       // log exception...
       base.HandleUnknownAction(actionName);
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top