views:

596

answers:

2

Hi,

I'm experimenting with ASP.NET MVC and Routes.

It appears MVC forces me to add a public method to the controller any time I want to create a view. For example:

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

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

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

I do not want to create a public method for every view. By default, I want the behavior of "return View()" for all views in the system, unless otherwise specified.

For example, HTTP GET:

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

As it stands now, I would have to add:

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

All result in "return View()". This is my problem, I am trying to eliminate creating public action methods for simple views.

For views that require additional processing, like a Contact Us page on an HTTP POST to:

site.com/contact-us

I would like to specifically add a method in the controller to send an SMTP message.


The following is a more concise example of what I am trying to do:

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

}

Thanks, Brian

A: 

I'm not sure i understand your question? Isn't this standart routing? You will omit the {action} in your route and hardcode it to a default for the specific cases?

http://www.asp.net/learn/mvc/tutorial-23-cs.aspx

Per Hornshøj-Schierbeck
Updated question, hopefully it's more clear about what I'm trying to do.
Brian Chavez
+3  A: 

The potential problem with having the ShowBasicView from your edit is that due to the implicit wiring of views, each of those urls will all return the same view, namely:

\Views\Home\ShowBasicView.aspx

Now, this might be what you want, although it's probably unlikely.

You could possibly set this up by having a route such as:

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

And modify your controller to:

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

Alternatively, if the content is hardcoded in the views you could try:

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

You'll possibly also have to add a route for the base URL, as the ShowBasic route will only hit for a URL with a string value.

Zhaph - Ben Duguid
I tried this, but pageName is null on every request. To root site.com/ and to site.com/about.
Brian Chavez
got it! thanks! Works beautifully.
Brian Chavez
just need to change {id} to {pageName} and it will work in the route.MapRoute()
Brian Chavez