I am trying to present a form to my user where they can enter a start postcode, hit a button and end up on a page offering driving directions to a known postcode.
The route I want to match is defined as:
routes.MapRoute("Directions", "Directions/{Name}/{StartPostCode}-to-{DestinationPostCode}", new { controller = "Directions", action = "Index" });
I am using the following code to present the form:
#using (#Html.BeginForm("Index", "Directions", new { DestinationPostCode = Model.postcode, Name = Model.nameURLized }, FormMethod.Get))
{
<input type="text" name="StartPostCode" id="StartPostCode" class="inputGreyed" value="Enter Postcode" onclick="ToggleDefaultText(this)"/>
<input type="submit" value="Get Directions" />
}
The problem is that I end up at /Directions/Index?StartPostCode=abc123. It is missing the destination postcode and the name key value pairs. This of course means I end up with my request being processed by the wrong route. I have proved this using Phil Haacks route debugger.
I have tested going directly to /Directions/TheName/ABC123-to-DT83PX which works as expected. In fact, I tried this using the following code to build a link:
#Html.ActionLink("Directions Generated", "Index", "Directions", new { StartPostCode = "ABC123", DestinationPostCode = Model.postcode, Name = Model.nameURLized }, new { #class = "button", #title = "More details on " + Model.name })
Any help will be much appreciated.
Please do the following:
a) add the default route:
routes.MapRoute(null, "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }
b) Pass the values for DestinationPostCode and ListingName in hidden input fields.
c) Use:
#using (#Html.BeginForm("Index", "Directions")) { your code }
Related
I've created a page which support editing multiple entities.
This page is called like: http://localhost/Personnel/EditMultiple?id=2944&id=7
On this page there is a GridView which should list these personnels in a grid.
This grid is defined like:
<% Html.Telerik().Grid<Web.Models.PersonnelMiniVM>()
.Columns(columns =>
{
columns.Bound(p => p.Name);
})
.DataBinding(d => d.Ajax().Select("_GetPersonnelByIds", "Personnel", new { personnelIds = string.Join(",", Model.PersonnelIds) }))
.Pageable(page => page.PageTo(Model.Page))
.Sortable(sorting => sorting.OrderBy(sortOrder => sortOrder.Add(p => p.Name)))
.Render();
%>
But when I look at the URL which is posted to the Personnel Controller, it's like:
http://localhost/Personnel/_GetPersonnelByIds/2944%2c7?personnelIds=7%2C2944&Personnel-size=5
What I don't understand is that why the 2944%2c7 is appended and this also gives me an 401 error when the URL gets too long.
The routing defined in Global.asax is like this:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
How to solve this ?
See this :
http://www.telerik.com/community/forums/aspnet-mvc/grid/mvc3-grid-control-ajax-bound-select-url-has-extra-route-values.aspx
Solution is to clear the id, like:
.DataBinding(d => d.Ajax().Select("_GetPersonnelByIds", "Personnel", new { id= "", personnelIds = string.Join(",", Model.PersonnelIds) }))
I have an MVC 3 view with the following code:-
#using (Html.BeginForm(MVC.Order.SearchResults(), FormMethod.Get))
{
#Html.AntiForgeryToken()
#Html.Button("btnSearch", "Search", HtmlButtonType.Submit, null, new { #class = "button primary icon search", alt = "Search the orders (up to 50 characters)" }
}
When I post the form I see the __RequestVerificationToken= and the contents of the verifcation token within the querystring.
Any ideas why this may be the case and how to sort it?
Anti forgery token work only with POST requests. If you want to use them you need to change the verb used of the form to POST instead of GET:
#using (Html.BeginForm(MVC.Order.SearchResults(), FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.Button("btnSearch", "Search", HtmlButtonType.Submit, null, new { #class = "button primary icon search", alt = "Search the orders (up to 50 characters)" }
}
There is a workaround how you can pass antiforegy value through GET method or even in headers. More details here.
How can I force URL first page without page number?
Here is the exact code I use.
routes.MapRoute("MyPictureQuotes",
"picture-quotes/{PictureQuotesPage}",
new { controller = "Quote", action = "PictureQuotes", PictureQuotesPage = UrlParameter.Optional }
);
<%= Html.RouteLink("Picture Quotes", "MyPictureQuotes", null, new { title = "Picture Quotes", PictureQuotesPage = string.Empty })%>
It returns
"/picture-quotes/5" instead of
"/picture-quotes" from the page
"http://localhost:2489/picture-quotes/5"
It seems the routing value page 5 is carried over.
Does anyone have a solution for this?
You are not using the correct overload of Html.RouteLink. Use the following:
<%= Html.RouteLink("Picture Quotes", "MyPictureQuotes",
new { PictureQuotesPage = string.Empty },
new { title = "Picture Quotes" })%>
My original question was a bit confusing, so let me edit this post to be more clear:
How can I generate an ActionLink that not only uses the Routing engine, but also takes you to an html element with particular ID on a page? I want to generate something like this:
<a href="/ControllerName/ActionName/#section2>Link</a>
or sometimes the same but with an action parameter of 15 for example:
<a href="/ControllerName/ActionName/15#section2>Link</a>
Where the View served by the actionName has an element with the id of "section2":
<div id="section1">
<h1>Section 1</h1>
...
</div>
<div id="section2">
<h1>Section 2</h1>
...
</div>
I believe that I could write a Html helper method that uses Url.RouteUrl() and then append the "#sectionId" but is this the easiest/best way to do this? Should I create a routing rule for this? The default route:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Experiment", action = "Index", id = "" }
);
allows me to manually add "#section2" to the end of the url in my browser and it takes me to the section2 div. It seems like rather than adding or changing a route I simply need to append "#section2" to the ActionLink url.
You would want to change/add a route to be:
routes.MapRoute("MyRoute", "{controller}/{action}#{id}", /* some default here */);
Then the MVC Helper would be:
<%= Html.ActionLink("Link Text", "Index", new { id = "sectionId" }) %>
For the following route:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}/{section}",
new { controller = "Home", action = "Index", id = "", section = "" }
);
you would do:
<%= Html.ActionLink("Link Text", "Index", new { section = "#sectionId" }) %>
I think the OP wants the ID to be the anchor ref at the end of the URL, as it appears to be a list of items and he wants the browser to scroll down to the item. (I'm just guesing here because of the "#" stipulation. Small edit to Mark's code:
routes.MapRoute(
"Default",
"{controller}/{action}/#{sectionId}",
new { controller = "Home", action = "Index", sectionId = Model.SectionId } );
I have the following route definition in a MapRoute Table:
routes.MapRoute(
"ViewDocument",
"browse/document/{document_id}/{document_title}",
new { controller = "Document", action = "ViewDocument"}
);
I have to create links of documents on document index view (document object have "id" and "title" property)
What should be my approach to generating the link in ASP.NET MVC?
Is there anything I am doing wrong with the route definition?
In your routes:
routes.MapRoute(
"ViewDocument",
"browse/document/{document_id}/{document_title}",
new { controller = "Document", action = "Title", document_id = "", document_title = ""}
);
In your View:
<%= Url.RouteUrl("ViewDocument", new { document_id = ... , document_title = ... }) %>
(renders plain url)
or
<%= Html.RouteLink("ViewDocument", new { document_id = ... , document_title = ... }) %>
(renders <a></a> element with href attribure filled with the url)
Won't you be able to find the proper Document simply based off its ID?
Won't the Title be redundant?
You can generate links to documents for the route given with the following:
<%= Html.ActionLink("Doc Link", "Title", "Document", new { document_id="id", document_title="title" }, null) %>
A couple of things to be aware of:
Your custom route must be added before the Default route.
You have to include the route values as shown above in order to have them specified in the link.