I have an action method that looks like this
public ActionResult MethodName(int num)
{
viewmodel model = GetDetails(num)
return View(model);
}
route config looks like this
routes.MapRoute(
name: "MethodName",
url: "{ControllerName}/{MethodName}",
defaults: new {controller = "controllerName", action="MethodName"}
);
My issue is it gives the URL of
www.mysite.com/controller/Method?message= 78545
I would like to have it as
www.mysite.com/controller/Method/78545
Can anyone please help me with this? How can I achieve this? I have tried making changes to route config with no help. Do I need to make any URL rewriting or will there be a small fix for this in route config?
Thanks.
Change your route mapping to have an optional num parameter:
routes.MapRoute(
"MethodName",
"{ControllerName}/{MethodName}/{num}",
new { controller = "controllerName", action = "MethodName", num= UrlParameter.Optional }
);
If you don't want your parameters to result in a querystring, you need to add optional parameters to your MapRoute. Then you load the parameter with the value you want to pass to the action result.
In the example below, you can access the method by calling it with "controller/action/op1" or "controller/action/op1/op2", you get the idea. (if op1 equals the value 1, the url will look like 'controller/action/1', same for the other parameters)
[ Add Optional Parameters ]
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{op1}/{op2}/{op3}",
defaults: new { controller = "Home", action = "Index", op1 = UrlParameter.Optional, op2 = UrlParameter.Optional, op3 = UrlParameter.Optional }
);
Related
How do I correct my routing to fix an issue with ajax .load()
I modified my route to my spacecontroller so that it looks like this
routes.MapRoute(
name: "SpaceCleanRoute",
url: "Space/{id}",
defaults: new { controller = "Space", action = "Index" }
);
so that I have a cleaner route and when a user wants to see a space the URL will look like this
www.mysite/space/12345
the problem I'm having now is when my JS file calls a .load() like this, , where spaceoverview is my action
$("#partialPageContainer").load('/Space/SpaceOverview', function (response, status, xhr) {
alert("Load was performed.");
});
I get an error saying
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'YogaBandy2017.Controllers.SpaceController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
So I have to put an id after the url like this, which is not what I want, or doesn't seem right to me
How can I fix this or is this just how the routing works? I'm kinda new to mvc routing with ASP.Net
$("#partialPageContainer").load('/Space/SpaceOverview/1', function (response, status, xhr) {
alert("Load was performed.");
});
UPDATED - I guess for now I'll just use '/space/actionname/1' to connect to each action, until I can find a better solution.
You can use parameter constraints to filter out string values for the id parameter.
routes.MapRoute(
name: "SpaceCleanRoute",
url: "Space/{id}",
defaults: new { controller = "Space", action = "Index" }
constraints: new { id = #"\d+" }
);
Then you need to have your default route set up to handle things that don't match that constraint:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The first route will catch your
/Space/12345
example, because 12345 matches the #"\d+" pattern, however the second route will handle your
/Space/SpaceOverview
example, because SpaceOverview does not.
You can find more information and examples of route constraints here: https://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/creating-a-route-constraint-cs
edit: I believe you can also use one of the built in routing constraints (which might work better, because technically a value could match the #"\d+" pattern but still not be a valid int), like this:
routes.MapRoute(
name: "SpaceCleanRoute",
url: "Space/{id}",
defaults: new { controller = "Space", action = "Index" }
constraints: new { id = new System.Web.Http.Routing.Constraints.IntRouteConstraint()}
);
If you want to send action parameter try this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I am trying to do some MVC routing, following online tutorials, but for some reason the routing is not working.
I am trying to do http://www.website.com/news/news-title
The route I am trying to do is below.
routes.MapRoute(
"News",
"{controller}/{url}",
new { controller = "News", action = "Index", url = "" }
);
Within my NewsController I have the following ActionResult.
public ActionResult Index(String url)
{
return View();
}
However, when stepping thorough the code, url is not being populated.
Thanks
== Update ==
Thank you all for your replies.
I have no amended the Route to below
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.LowercaseUrls = true;
routes.Add(new SubdomainRoute());
routes.MapRoute(
"News",
"News/{action}/{slug}",
new { controller = "News", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
This URL works: /news/index/?slug=test-news-title
But this URL does not: /news/index/test-news-title
=== Further Edit ===
It appears my subdomain route is messing with it. If i remove the subdomain route it works fine.
Thanks.
Most likely, your route is too broad. But it depends on how the rest of your routes are configured. You would need to post your entire route configuration (including area routes and attribute routing) in order to reasonably get an answer what is wrong with your route.
However, you can be more specific with this route because you know that it needs to start with /News.
routes.MapRoute(
"News",
"News/{url}",
new { controller = "News", action = "Index" }
);
Also, it probably doesn't make sense to make the URL parameter optional by providing a default value. If you remove url = "", the url parameter is required in the URL. If configured as above, if you just pass /News, it won't match this route. However, as you have it this URL will match.
Finally, make sure this route is placed in the right order. It should be placed before your default route (if you still have it).
You have set for the parameter url the empty string. you should use instead UrlParameter.Optional (or removing it at all if is mandatory):
routes.MapRoute(
"News",
"{controller}/{url}",
new { controller = "News", action = "Index", url = UrlParameter.Optional }
);
You are missing the action part in the MapRoute
routes.MapRoute(
"News",
"{controller}/{action}/{url}",
new { controller = "News", action = "Index", url = "" }
);
Hope this help
In my MVC application, I have following route configuration,
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Now if i give some thing like this, localhost:56789/prd1/Home/Index
The first routing is working.
However if i directly access localhost:56789/Home/Index or any other controller action, like localhost:56789/Account/Login the routing is not working.
Is it because I have a {productName} defined?
For testing purpose how can I add few products like prd1, prd2 along with routing?
Routes are matched against the request in the order they are defined. When a route matching the request is found, no further routes are considered. Thus, you need to list your routes in order of decreasing specificity.
However, your first route matches more requests than your second route, i.e. it is less specific than the second route:
When ASP.NET MVC tries to match the request for Home/Index to your routes, it will match the first route because it will consider Home to be the productName, it will consider Index to be the controller name and the rest of the parameters are not required.
You need to reorder your routes or make the first route more specific. This could be done by putting constraints on the productName parameter.
UPDATE
Without knowing anything about your products and their names, it is impossible for me to suggest an appropriate constraint. Maybe you could use a numeric SKU and have a constraint like
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { productName = #"\d+" }
);
forcing productName to be numeric.
Alternatively, you could change the url to
"products/{productName}/{controller}/{action}/{id}"
For more on constraints see this link or use Google.
For route configuration
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
defaults: new { productName = 'put your method name to get productName over here', controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "your namespace of controller" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Let's look at these two routes mapped in RouteConfig.cs, one with a guid and one without:
// Non-guid route
routes.MapPageRoute(
name: null,
url: "dashboard/{action}",
defaults: new { controller = "Dashboard", action = "Index" }
);
// Guid route
routes.MapPageRoute(
name: null,
url: "{guid}/dashboard/{action}",
defaults: new { controller = "Dashboard", action = "Index" }
);
And the method call:
UrlHelper.Action("Index", "Dashboard", new { guid = "c73b47b9-4ad5-414a-a92e-8937231f8e2bD" })
The method returns this:
"/dashboard/?guid=c73b47b9-4ad5-414a-a92e-8937231f8e2b"
But I'm expecting this:
"/c73b47b9-4ad5-414a-a92e-8937231f8e2b/dashboard/"
Note that it's putting the guid as a querystring value instead of the first parameter.
Now if I hardcode that second url the app uses the correct guid route and also works if I use route names instead (UrlHelper.RouteUrl) so I don't think it's an issue with the route mappings themselves. Neither of these solutions will work well with our application as we have hundreds of routes and currently using UrlHelper.Action all over the place.
I've also tried pretty much every overload and variation of UrlHelper.Action, including passing a RouteValueDictionary instead of an anonymous object.
This is an ASP.NET MVC 4 web application.
Any ideas to why this isn't working? (or alternatives, maybe using one route)
Try this. Put the more specific route first:
routes.MapRoute(
name: "WithGUID",
url: "{guid}/dashboard/{action}",
defaults: new { controller = "Dashboard", action = "Index" }
);
routes.MapRoute(
name: "NoGUID",
url: "dashboard/{action}",
defaults: new { controller = "Dashboard", action = "Index", guid = "" }
);
I'd like to tidy this url if at all possible.
Curently it looks like this which is returned from an ActionResult GET
http://localhost/Controller/Action?City=SomeCity&GeoLat=00.000&GeoLong=-0.00000494
Here's what I'm trying to achieve
http://localhost/Controller/Action/SomeCity?GeoLat=00.000&GeoLong=-0.00000494
The City parameter isn't used for anything, so manually editing the first url into the second does indeed return the correct data.
I've even tried appending int the City variable to the action, not really ideal.
routes.MapRoute(
"Default",
"{controller}/{action}-{City}/",
new { controller = "House", action = "Location", City = UrlParameter.Optional }
);
Thanks!
You were almost there with the routing change. Add this code BEFORE the default route
routes.MapRoute(
"CityRoute",
"{controller}/{action}/{City}",
new { controller = "House", action = "Location" }
);
Note that I change the url format slightly and removed the optional parameter part (it's not needed)
as I correct understand, this will be solution for you:
routes.MapRoute(
name: "City",
url: "House/Location/{City}",
defaults: new { controller = "House", action = "Location" }
);
Controller:
[HttpGet]
public ActionResult Location(string City, string GeoLat, string GeoLong){ }
what is more - you have to add this before default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Account", action = "Index", id = UrlParameter.Optional }
);
at least, now you will be able to achieve GeoLat and GeoLong value, as also City parametr, in your controller method.
To get the url you're after in MVC 4 you have two options
Map a route with a city param:
routes.MapRoute(
"City",
"{controller}/{action}/{city}",
new { controller = "House", action = "Location", city = UrlParameter.Optional }
);
Rename you city param to id and use the default route mapping.
(MVC 5 introduces the RouteAttribute class that allows you to specify mappings on individual Actions.)