Match Route Only if specific Parameter - c#

I am trying to create a route that only matches if a specific parameter is used in the URL.
For example:
routes.MapRoute(
name: "BannerAds",
url: "Go/{Web}",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds", web = UrlParameter.Optional }
);
I want the URL to match for http://www.domain.com/Go/Web?=111222
But not for http://www.domain.com/Go/Advertising
How do I change my route to function this way?

You would need to make that part of the url static in your route then:
routes.MapRoute(
name: "BannerAds",
url: "Go/Web",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds" }
);
And then place that route above a your more general one:
routes.MapRoute(
name: "BannerAds",
url: "Go/{Web}",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds", web = UrlParameter.Optional }
);

like this
routes.MapRoute(
name: "BannerAds",
url: "Go/Web",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds", web = UrlParameter.Optional }
);
if you actually only want to catch
http://www.domain.com/Go/Web?x=111222
then write the controller to check for query strings
edit
?=111222 isn't a proper query string - I don't really get why you want to catch that - usually there is key value pair , like ?key=111222 or ?x=111222 when writing like that you can check for the value of x or key and if it equals 111222 , then do something

You should be able to just do this:
routes.MapRoute(name: "BannerAds",
url: "Go/Web",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds", web = UrlParameter.Optional });
And manually parse the query string in the controller like this:
public ActionResult BannerAds()
{
string idStr = Request.QueryString.ToString().Trim('='); // strip of leading '='
int id;
if (!int.TryParse(idStr, out id))
{
return HttpNotFound();
}
...
}

Related

Changes to query string in the url

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 }
);

asp.net mvc routing - map actions not controllers

I know it's more of the same (SO has more than 5,600 questions on this), but I've been sitting on this one for a couple of days now so I guess it was the right time to ask a question.
My requirements
I want to have the following routes in my asp.net mvc app:
myapp.com/sigin -> Controller = Account, Action = SignIn
myapp.com/signout -> Controller = Account, Action = SignOut
myapp.com/joe.smith -> Controller = User, Action = Index
myapp.com/joe.smith/following -> Controller = User, Action = Following
myapp.com/joe.smith/tracks -> Controller = Tracks, Action = Index
myapp.com/about -> Controller = About, Action = Index
Any other default route, so that's why I left the standard one there.
My Code
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "About",
url: "about",
defaults: new { controller = "About", action = "Index" }
);
routes.MapRoute(
name: "MyTracks",
url: "{username}/tracks",
defaults: new { controller = "MyTracks", action = "Index" }
);
routes.MapRoute(
name: "MyTunes",
url: "{username}/tunes",
defaults: new { controller = "MyTunes", action = "Index" }
);
routes.MapRoute(
name: "MyProfile",
url: "{username}",
defaults: new { controller = "User", action = "Index"},
constraints: new { username = "" }
);
routes.MapRoute(
name: "Account",
url: "{action}",
defaults: new { controller = "Account" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Issue
Routes number 3 and 4 just don't work as they get mixed up with route 1 and 2. I have tried debugging my code with Phil Haack's routing debugger, but no luck. Any ideas what I am doing wrong?
The problem is in your last two custom routes. All the routing framework has to work with is just a single token from the URL, and two possible routes to match it with. For example, if you attempt to go to the URL, /signin, how is the routing framework supposed to know there's not a user with username "signin". It's obvious to you, a human, what should happen, but a machine can only do so much.
You need to differentiate the routes in some way. For example, you could do u/{username}. That would be enough to help the routing framework out. Short of that, you'll need to define custom routes for each account action before the user route. For example:
routes.MapRoute(
name: "AccountSignin",
url: "signin",
defaults: new { controller = "Account", action = "Signin" }
);
// etc.
routes.MapRoute(
name: "MyProfile",
url: "{username}",
defaults: new { controller = "User", action = "Index"},
constraints: new { username = "" }
);
That way, any of the actual action names will match first.

MVC Routes interference issues

I want to have the following:
Link to {controller}/{destination} and link to {controller}/{action}, for example: flights/berlin and flights/search accordingly.
My routes config is as follows:
routes.MapRoute(
name: "LandPage",
url: "{controller}/{destination}",
defaults: new { controller = "Flights", action = "Index", destination = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
If "LandPage" is first, the route will go always to the land page with the url parameter (i.e. --> flights/search will go to flights/index with parameter destination = search) and its bad for me.
If "Default" will be first, and I try to navigate to flights/berlin, it will try to navigate to the flights controller and action = berlin, of course no such action...
The only solution I can think of is using "LandPage" first, and compare the {destination} parameter with name of action and redirect to that action... I don't like that solution... anyone can think about another solution??
Thanks!
You can set fixed routs for specific actions:
routes.MapRoute(
name: "Search",
url: "Flights/Search/{search}",
defaults: new { controller = "Flights", action = "Search", search = UrlParameter.Optional }
);
and
routes.MapRoute(
name: "LandPage",
url: "Flights/{destination}",
defaults: new { controller = "Flights", action = "Index", destination = UrlParameter.Optional }
);
before your default route.

OR operator in MVC URL pattern

I'm writing an MVC route and i was wondering, can i use something like an OR operator in it?
Something like this, where my Urls can either start with "shop/" or with "articles/"?
routes.MapRoute(
name: "Default",
url: "shop|articles/{action}/{id}",
defaults: new { controller = "Store", action = "Index", id = UrlParameter.Optional }
);
You could use a route constraint where you specify the valid values separated by pipes.
routes.MapRoute(
name: "Default",
url: "{page}/{action}/{id}",
defaults: new { controller = "Store", action = "Index", id = UrlParameter.Optional },
constraints: new { page = "shop|articles" });

Route base/id to controller/action/id in mvc 4

I want to redirect users when they enter a URL into the browser based on the ID. For example, a user enters:
http://localhost:50431/10213
and they will be redirected to:
http://localhost:50431/home/job/10213
Default Route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{jobno}",
defaults: new { controller = "Home", action = "Job", jobno = UrlParameter.Optional }
);
How can I achieve this?
You could try something like this:
routes.MapRoute(
name: "Job Number",
url: "{jobno}",
defaults: new { controller = "Home", action = "Job" },
new { jobno = #"[0-9]*" }
);
And put it above the other route. The added parameter is to avoid the route catching urls like http://localhost:50431/foobar, but only the ones that contain numbers.
Please note I don't have a way of testing this at the moment so you may have to tweak it slightly.
I think this is the best solution:
routes.MapRoute(
name: "Job Number",
url: "{jobno}",
defaults: new { controller = "Home", action = "Job", .jobno = UrlParameter.Optional },
constraints: new { jobno = #"[0-9]*" }
);
I have tested this and it works properly, his reply in the comment did not work properly for me.

Categories

Resources