Action parameters showing up in querystring instead of URL - model-view-controller

I'm doing this:
#Url.Action("Details", "MyController", new { id = this.Model.ID })
The URLcomes out like this: /MyController/Details?id=1
How do I get it to format the URL like this: /MyController/Details/1
The routes look like this:
routes.MapRoute("Default", "{Controller}/{Action}", new { Controller = "Home", Action = "Index" });
routes.MapRoute("Default-ID", "{Controller}/{Action}/{ID}");

The order of routes matters - both urls are valid, and in this case the system gets to the query string one first when looking for a url matching that action.
There's also a possibility you have a case sensitivity issue with {ID} - not sure about that one, but generally it is best to use case consistently.

Related

Can we use just the controller name and id parameter in URL for Asp.net MVC application

Suppose, I have a controller named category with an action method, Index which takes id as parameter.
Therefore, the URL appears like this : category/Index/foo. As you can see, the Index segment just doesn't seem right. A URL such as this : category/foo will be more readable and understandable.
Just like in SO, these guys use : question/857344
How can I achieve such a URL. In my routes, I have set defaults for all three : controller, action and id. But, when i try to visit category/foo, I get the "404 - resource not find"
routes.MapRoute(
"Category/{id}",
new { controller = "Category", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
You map it how you want it to look then specify the Action.
Also make sure you put it before the default route

Url routing - infinite url

I use asp.net mvc3 and I want to write route that has no end..
I mean something like that:
www.site.com/Cameras/{id}={string}/{id}={string}/{id}={string}/{id}={string}.....
where the id represent a filter id and the string represent a value of that filter..
I have many types of filters and in the future I want to be able to add more without any dependence..
How should this kind of route should look? And how do I start to deal these parameters?
What you need to do is write a catchall route and then interpret it like this:
routes.MapRoute("Cameras", "cameras/{*url}",
new { controller = "Cameras", action = "Index" }
);
public ActionResult Index(string url)
{
var ids = url.split('/');
// now do what you need with the ids
}
You should use urls like this:
/cameras/id1/id2/id3/id4

route that will handle URL's in the URL for MVC 3

I am trying to create a custom route that can handle something like:
domain.com/link/http://www.someotherdomain.com/blablah.html?qstring=54
Where the passed param is a link...
I cannot get this to work with URL encode and decode.. always returns a bad request?
Pass the link as id.
Something like...
controller:
public SomeAction(string url)
{
...
}
View:
#Html.ActionLink("link name", "Action", new {id = "someurl.com"}
or modify the global.asax's routes.MapRoute and add another parameter.

Route with optional parameter is not resolved correctly

Here is necessary code to reproduce a very strange problem with ASP.NET MVC 3.0 routing:
Route registration in Global.asax.cs:
routes.MapRoute("History", "Customer/History", new {controller = "User", action = "History", someParam = UrlParameter.Optional});
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Here we declare a route to the user's history. But in the URL we want "Customer" instead of "User". Also please note parameter someParam. Controller User does really exist and has action History.
Now usage in view:
History
History with param
I am using here Url.Action() instead of Html.ActionLink() only for clarity.
And here is the result - how this part of the view was rendered:
History
History with param
Now the problem is clear - URL without parameters was resolved correctly, while the URL with parameter starts with "/User" instead of "/Customer".
Questions:
Is it a normal behavior? If yes, why does routing work that way?
Is there any workaround for this? I mean is there any way to get the final result as:
History
History with param
I suspect it's getting confused because your route for Customer doesn't list that extra value, but the default one does. Try this:
routes.MapRoute("History", "Customer/History/{someParam}", new {controller = "User", action = "History", someParam = UrlParameter.Optional});
Or to preserive the query string link syntax, this:
routes.MapRoute("History", "Customer/History/{id}", new {controller = "User", action = "History", id = UrlParameter.Optional});
In the second case you don't supply a value for id when creating the link (your call to Url.Action shouldn't have to change).

ASP.NET MVC Routing help

I am trying to create a route that can allow for different formats (html/json/xml etc)
This is what I am trying, but it doesn't work.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}/{format}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional, format = "html" },
new { format = #"html|json" , id=#"\d+"}
);
The routes that do work are these:
/Person/details/1
/Person/details/1/json
But this don't work:
/Person which imo should default to /Person/Index/html
/Person/json and imo should lead to /Person/Index/json
But it doesn't match.
For the second of the ones that don't work I assume it thinks json is an action and that's the problem there, but for the first one I don't fully get it as I have defaults for each part of the url, and id is optional and it can't think html/json is the id as I say id have to be a number anyway, so it should imo get that one.
So who aren't the first one working?
For the second one I have been meaning to write a regex like this (I know it's not a real regex btw, any help on that is also appreciated..): action = #"!(html|json|\d+)" so that it will see that I'm not trying to say that json/html is an action, but that it then should use the default action of index.
But since the first one isn't even working I think I have to resolve that one first.
The problem
Routes can have multiple optional parameters (although I suggest you don't use this unless you know Asp.net MVC routing very well), but you can't have non-optional parameters after optional ones as you've done it...
Imagine what would happen if you set a non-default "json" value for your format but don't provide id? What would come in place of the id? You'd run against a very similar problem with multiple optionals, hence I advise you not to use them.
Two solutions
Change parameter order:
"{controller}/{action}/{format}/{id}"
Use two routes
routes.MapRoute(
"Ordering",
"{controller}/{action}/{format}",
new { controller = "Home", action = "Index", format = "html" },
new { format = #"html|json|xml"}
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}/{format}",
new { controller = "Home", action = "Index", format = "html" },
new { format = #"html|json|xml", id = #"\d+"}
);
The first one will cover requests where ID is optional and you do provide format, and the second one will cover situations when ID is present.
The id parameter cannot be optional. Only the last parameter of a route definition can be optional.

Resources