Alex P
Alex P

Reputation: 12497

How do I refer to a constant URL in my route configuration?

Suppose I have the following within a webpage

<% using (Html.BeginForm("ShowData", "Summary")) %>
<% { %>
<div class="dropdown"><%=Html.DropDownList("CourseSelection", Model.CourseList, new { @class = "dropdown",  onchange="this.form.submit();" })%> </div>
<% } %>

When the user makes a selection from the dropdown the form is submitted and I would like it to link to another page with a URL as follows:

http://localhost:1721/Summary

I have the following routes:

    routes.MapRoute(null, "Summary", new { controller = "Summary", action = "ShowData", CourseSelection = (string) null });

    routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Login", action = "Index", id = UrlParameter.Optional });

When a user selects an item in the dropdownlist, the URL returned is:

http://localhost:1721/Summary/ShowData?CourseSelection = UserSelection

Clearly the first route in the list is not being matched.

I don't want the URL to show the action name and parameter. I simply want to show "Summary" which is what I have hard coded in the URL. How do I achieve this?

Upvotes: 1

Views: 1217

Answers (2)

Haacked
Haacked

Reputation: 59061

The problem here is that your route has a default value

CourseSelection = (string)null

Which is not part of the route URL (aka "Summary").

There's special logic when generating a URL that any default values for the route, where the parameter is not in the URL, the parameter you specify must match the default values.

So another way to fix this is:

using (Html.BeginForm("ShowData", "Summary", 
  new {CourseSelection = (string)null})) {
  ...
}

However, since you're posting that value to the action, I don't see why you have CourseSelection as a default in your route. You just need it as an action method parameter and it will automatically get bound when it's in the posted form data.

So an alternate solution is to change your route like so:

routes.MapRoute(null, "Summary", 
  new { controller = "Summary", action = "ShowData" });

Upvotes: 2

Raj Kaimal
Raj Kaimal

Reputation: 8304

When you view the html source for this,

 <% using (Html.BeginForm("UpdateView", "MyController")) %> 
    <% { %> 
    <div class="dropdown"><%=Html.DropDownList("Selection", Model.List, new { onchange="this.form.submit();" })%></div>          
    <% } %> 

you will notice that the action is empty. This is because the helper is unable to find a route based on what you provided in the BeginForm.

Based on your definition in Global.asax, all request will default to the Index action method. What you want, instead, is:

 routes.MapRoute("Default", "{controller}/{action}", new { controller = "Home", action = "Index" });  

Note the additon of the action in the URL pattern.

This works for me.

Global.asax

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(null, "Summary", new { controller = "Summary", action = "ShowData", CourseSelection = (string)null });

    routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Login", action = "Index", id = UrlParameter.Optional }); 

}

SummaryController

public class SummaryController : Controller { // // GET: /Summary/

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

public ActionResult ShowData(string CourseSelection)
{
    return View();
}

Code in the default view

<%
    var list = new List<string> { "a", "b", "c" };

    var selList = new SelectList(list); %>
<% using (Html.BeginForm("ShowData", "Summary")) %>
<% { %>
<div class="dropdown">
    <%=Html.DropDownList("CourseSelection", selList, new { @class = "dropdown",  onchange="this.form.submit();" })%>
</div>
<% } %>

}

Upvotes: 0

Related Questions