Routing issue with MVC - asp.net-mvc

I'm working with MVC 3 and have an issue. Instead of giving mydomain/mydirectory/item like I expected I get this:
mydomain/mydirectory/list?animal=quack.
Here's the route in the global
//Default route mapping
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = #"[^\.]*", action = #"[^\.]*" }
);
Code showing how I'm building the link:
<div id="main-content" title="AnimalBox" style="float:none;">
<% Html.DataList(Model.PriceListAnimals).Columns(7).Item(item =>
{
item.Template(galleryImage =>
{%>
<div style="margin-left:20px; line-height:150%;">
<span><%= Html.ActionLink(galleryImage.AnimalName,"List",new { #animal = galleryImage.AnimalName }) %></span>
</div>
<% });
}).Render(); %>
</div>
Any ideas?

You have to define a route for special case routing like your instance. Since you are passing 'animal' as a parameter, you should create a route to handle that instance. In your global.aspx (above the default route), create something like below:
routes.MapRoute(
"Animal", // A distinct Route name
"{controller}/{action}/{animal}", // URL with parameters
new { controller = "MyDirectory", action = "List"}
);
This will define a route to the MyDirectory controller on the action list which has an animal parameter which is NOT OPTIONAL. Defining routes is what enables you to generate clean URLs from the html helpers and other methods (redirect to action, etc).

The overload for Html.ActionLink is:
Html.ActionLink("linkText", "actionName", "controller", object routeValues, object HtmlAttributes)
From what you've said, mydirectory = controller, and List = action, correct? If so, try:
<%= Html.ActionLink(galleryImage.AnimalName, "List", "mydirectory", new { #id = galleryImage.AnimalName }, null) %>
this should produce:
quack

Related

Display query string in specific format in mvc form

when we submit form with get method, it pass parameters as querystring like below:
http://localhost:2564/Blog?SearchManufacturer=land
But, I want to display query string like below:
http://localhost:2564/Blog/SearchManufacturer/land
I have tried below code. but still it passing with query string.
#using (Html.BeginForm("Index", "Blog", new { CurrentFilter = Model.SearchManufacturer }, FormMethod.Get))
{
<div class="form-group col-lg-4 col-md-6 col-sm-6 col-lg-12">
<label>Search Manufacturer</label>
#Html.TextBoxFor(x => x.SearchManufacturer, new { #class = "form-control" })
</div>
<div class="form-group col-lg-4 col-md-6 col-sm-6 col-lg-12">
<input type="submit" value="Search" class="submit" />
</div>
}
also, in route.config, I have used different combinations of routing as below.
routes.MapRoute("Blog", "Blog/SearchManufacturer/{SearchManufacturer}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyPageSortandFilter", "Blog/Page/{page}/CurrentFilter/{currentFilter}/SortBy/{sort}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyPageandSort", "Blog/Page/{page}/SortBy/{sort}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyPageandFilter", "Blog/Page/{page}/CurrentFilter/{currentFilter}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbySortandFilter", "Blog/SortBy/{sort}/CurrentFilter/{currentFilter}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("SortBlog", "Blog/SortBy/{sort}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyPage", "Blog/Page/{page}", defaults: new { controller = "Blog", action = "Index" });
routes.MapRoute("BlogbyFilter", "Blog/CurrentFilter/{currentFilter}", defaults: new { controller = "Blog", action = "Index" });
these routing are used for sorting, paging, filtering using Pagedlist.mvc. all these are working fine. but searching is not passing parameter as in routing. it is passing parameter as query string.
please help me to fix this.
Thanks
Lalitha
If your form method is set to GET type, when you submit the form, form data will be appended to the action attribute url as querystring values (which starts with ?). This is something the browsers does. Your asp.net mvc routing cannot do anything on this.
If you absolutely need the /Blog/SearchManufacturer/land url when the form is submitted, you can hijack the form submit event with client side javascript and update the url however you want. The below code will give you the output you want.
$(function () {
$("#searchFrm").submit(function (e) {
e.preventDefault();
var formAction = $(this).attr("action");
if (!formAction.endsWith('/')) {
formAction += '/';
}
var url = formAction +'SearchManufacturer/'+ $("#SearchManufacturer").val();
window.location.href = url;
});
});
Assuming your form tag has an Id value "searchFrm"
#using (Html.BeginForm("Index", "Blog",FormMethod.Get,new { id="searchFrm"}))
{
// Your existing code goes here
}

Mvc: Exclude id from url

I have the next foreach in my cshtml page, it allows to me iterate in each Model item
#foreach (var item in Model)
{
<div class="date">
#item.pubDate
</div>
<a href="#Url.RouteUrl("Details", new { action = "Details", controller = "News", id = item.id, title = item.title })">
<img src="some route" alt="some alt" />
</a>
}
so now it's working fine and each element inside foreach loop has an url with something like
http://something.com/News/Details/1/first-title
http://something.com/News/Details/2/second-title
It's possible create urls with something like
http://something.com/News/Details/first-title
http://something.com/News/Details/second-title
but i can still sending id parameter to my controller ?
Thanks in advance
Add another route:
routes.MapRoute(
name: "NewsTitleRoute",
url: "News/Details/{id}/{title}",
defaults: new {
controller = "News",
action = "Details",
id = UrlParameter.Optional,
title = UrlParameter.Optional
}
);
In your controller declare the details method like this, with the two parameters as optional:
public ActionResult Details(int? id, string title="")
{
}
That route configuration and Details method will work for:
http://something.com/News/Details/
http://something.com/News/Details/1
http://something.com/News/Details/first-title
http://something.com/News/Details/1/first-title
You can just pass the title property for id parameter.
#Url.RouteUrl("Details",
new { action = "Details", controller = "News", id = item.title})
Then set type of id parameter as string in your action method:
public ActionResult Details(string id)
Or you can create custom route like in von-v's answer. Just make sure it's above the default route.

URL parameters not appearing in ASP.MVC when using variant of Html.BeginForm

I've got a view that defines a form as
<% using (Html.BeginForm( "Update", "CcisCase", FormMethod.Post, new { id = "ccisEditForm" } ))
with a submit button:
In the RegisterRoutes method (in the HttpApplication-derived class in global.asax.cs), I've got:
routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
routes.MapRoute(
"CcisCase",
"CcisCase/{action}/{cmDatabaseId}/{caseId}",
new { Controller = "CcisCase", Action = "CcisCaseEdit", caseId = "" } );
The url generated by MVC ends with "/Update" but there are no parameters. What am I doing wrong?
Thanks,
Bob
What parameters are you expecting to see? A post does not append parameters to the querystring, a FormMethod.Get would. And, that overload with the id is the collection of HTML attributes to render for the tag (which I'm assuming you knew, but just in case).
HTH.
Your route contains a parameter {caseId} but your BeginForm only defines an id value.
new {id = "cssEditForm"}
You need something like this to include the caseId value
using (Html.BeginForm( "Update", "CcisCase", FormMethod.Post, new { caseId = 1, id = "ccisEditForm" }
If your action isn't using the id="ccisEditForm" value then you can remove that for less code clutter.
I figured out what my problem was. I had to pass the existing route data as follows:
using (Html.BeginForm( "Update", "CcisCase", ViewContext.RouteData.Values, FormMethod.Post, new Dictionary<string, object> { { "id", "ccisEditForm" } } ))

Can you use the HtmlHelper.Actionlink() method to create RESTful URLs?

I have some code like this:
<a href="<%= Html.ActionLink(
e.Member.UserName,
"profile",
"members",
new {username = e.Member.UserName}, null) %>"/>
The links it generates look like this:
http://mywebsite.com/members/profile/?username=scottm
Is it possible to make the link this:
http://mywebsite.com/members/profile/scottm
without having to do this:
<%= e.Member.UserName %>
Yes, you just need to set up another route.
routes.maproute(
"Profiles",
"members/profile/{UserName},
new { controller = "Members", Action = "Profile", UserName = "" }
}
I think a route like this may work. Did you try it?
routes.MapRoute(
"DefaultRest", // Route name
"members/profile/{username}", // URL with parameters
new { controller = "Members", action = "Profile", UserName = "" } // Parameter defaults
);

Html.ActionLink for non-standard routing

I have a route definition like this:
routes.MapRoute(
"Pagesize",
"{controller}/{action}/pagesize/{pagesize}",
new { controller = "Home", action = "Index", pagesize = 10 }
);
When I use
<%= Html.ActionLink("MyText", "myaction", new { pagesize = 10 }) %>
it renders as
MyText
I can understand I am misusing ActionLink since I have /pagesize/ in between. How can I correctly use it to create the link?
MyText
Please note that I am using mvc RC2 and no other helper libraries. The generic ActionLink no longer exists in RC2.
Try:
<%= Html.RouteLink("MyText", "Pagesize", new { controller = "Home", action = "Index", pagesize = 10 })%>
have you tried specifying the defaults in the map route command
routes.MapRoute("Pagesize",
"{controller}/{action}/pagesize/{pagesize}",
new {pagesize = 10 },
new { controller = "Home", action = "Index" });

Resources