C# MVC, Action Method doesn't read the parameter from QueryString - c#

This must be a small thing, but I am not able to figure out the issue.
I am passing 2 parameters through Querystring, but my index method receives only one of them. Not sure what could be going wrong here.
Here's my Index method
public ActionResult Index(Guid? empGuid = null, Guid? empPriorGuid = null)
{
// do something
}
And here's my URL :
baseurl/?empGuid=7a3b9a5d-b7dd-4959-a1df-be35546d2db7&empPriorGuid=f530733e-ce8d-4bbf-8480-3551dce91337
My Index seems to receive the empPriorGuid but not the empGuid for some reason.

IF you are using Areas you need to define a route having 2 parameters

I was able to figure out the issue, it was just a strange case that something was wrong with the empGuid, when I used a different Guid it did work. Thank you all!

you can change route config as below :
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{empGuid?}/{empPriorGuid}");
the "?" in routing means optional
and call action as below :
#Html.Action("index", "home", new { empGuid =7a3b9a5d-b7dd-4959-a1df-be35546d2db7,empPriorGuid=7a3b9a5d-b7dd-4959-a1df-be35546d2db7})

Related

Route variables received as action variables?

I've got the following route configuration:
routes.MapRoute(
name: "Default",
url: "{project}/{version}/{controller}/{action}",
defaults: new { controller = "Portal", action = "Index" }
);
The idea is to have two custom parameters in the URL, before anything else so an action filter I created can do a few useful things. That works well so far, but here's the problem.
Here's an action method with a parameter called version
public ActionResult SomeMethod(string version)
{
//Some logic has been performed using the custom route variable values before getting in here....
}
If I do the following call: http:/server/RouteValue1/RouteValue2/MyController/SomeMethod?version=1
The value of the version parameter of SomeMethod is RouteValue2.
Is there any way to tell the framework not to do that? Keep route variables seperate from action variables ?
No, you can't use the same parameter name in both the route config and as a query string. You'll need to rename one, i.e.:
http:/server/RouteValue1/RouteValue2/MyController/SomeMethod?ver=1

Where is Url.Action getting these values from?

I'm trying to create a link to the following GET action with Url.Action:
public class FooController : Controller
{
[HttpGet]
[Route("Foo/Apply/BarDetails/Part/{id}")]
public IActionResult BarDetails(int id)
{
}
}
And in my view I'm creating a URL with
Url.Action("BarDetails", "Foo", new {id = 1})
However this generates the URL Foo/Apply/BarDetails/Part/10?id=1 which is definitely not what I want! Removing the values parameter simply removes the query string part of the URL. The only route I have registered at startup is
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
I've had a look at the ASP.NET Core source and I suspect that the "10" part of the URL is coming from a "1" + "0" operation somewhere as the routing code is split across 2+ repos it's hard to follow. Does anyone know how the last part of this URL is being generated and how I can fix it to match the id provided in the route values?
It turns out that routing has changed between MVC5 (where this controller was written) and ASP.NET Core 2. It's also related to the way I've structured my controller. Basically at some point the list of possible routes gets sorted by the URL so Foo/Apply/BarDetails/Part/10 gets sorted to the top of the list and as this matches the requested URL, it gets returned. For the full details, see this GitHub issue.
You can set maximum and minimum range of optional route parameter in attribute based routing. Follow the code below
enter code here [Route("Licence/Apply/Details/Part/{id:int:max(1000):min(10)}}")]

How routing works in ASP.NET MVC4

I'm developing an ASP.NET MVC4 application and I'm new. I have two MapRoutes for routing.
routes.MapRoute("Char",
"ABC/Alpha/{number1}",
defaults: new { Controller = "ABC", action = "Alpha" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id=UrlParameter.Optional }
);
I didn't assign any default value to the number1 in the MapRoutes. But I know it is mandatory because it is in the URL path.
If I didn't provide any parameter in the url (when I run the app), I should get an error but I didn't.
Eg.:
http://localhost:32066/ABC/alpha/value---- getting desired output.
http://localhost:32066/abc/alpha/ ---- expected an error but there is no error.
Can anyone help me?
It doesn't match the first route, but it matches the second route. So it gets the controller/action = ABC/Alpha, and Id is optional.
Kyle is right, the second route (which is the global default) matches the url which is valid hence you don't see an error. I am guessing you are following one of the official Microsoft training videos that simulates an error in the request due to bad url that does not honor the route path.
To simulate the error, remove the default route, compile the project and run. Only this time specify the second url you have listed you should see the error.
Hope this helps.
The Route path is checked from top to bottom,
so in the first case
{Controller}/{Action}/{ID}
is passed by you (mention the id is must here) so the First routepath works
but Magic you was expecting the second case to throw an error, and it should have because if
your Action is like
public ActionResult ActionName(int id)
{
//some Code
}
then for sure it would have thrown error like Action
"Cannot convert null to 'int' because it is a non-nullable value type"
and i'm Pretty sure your Action will be having either
public ActionResult(int? id)
{//Some Code here}
or
Public ActionResult()
{
//Some Code here
}

ASP MVC Simple View not working

I set up a Route in a standard MVC router in global.asax, using MapRoutes. looks like this
routes.MapRoute(
null, //route name
"AddUnregisteredUser/{phonenumber}", //params
new { controller = "User", action = "AddUnregisteredUserFromPhoneNumber" }
);
UserController.AddUnregisteredUserFromPhoneNumber returns a View that displays two ViewData["key"] values...
whenever i debug the project, and call LOCALHOST:PORT/AddUnregisteredUser/1234567890 I get nothing. I put breakpoints in teh controller function and its not even going to the controller function. I put breakpoint in the global.asax and it never sets up the route when starting the asp.net development IIS server....
I dont see what is wrong with my code. any help would be appreciated.
Try supplying a route name instead of null.
Also, you might want to use RouteDebugger from RouteMagic to verify your route definition.
You need to supply a route name as well as add phonenumber to your route values as follows:
routes.MapRoute(
"route1", //route name
"AddUnregisteredUser/{phonenumber}", //params
new { controller = "User", action = "AddUnregisteredUserFromPhoneNumber", id = UrlParameter.Optional}
);

How to define this route in ASP.NET MVC?

I have a controller named Movie, with an action named ByYear, which takes the year as a parameter :
public ActionResult ByYear(int year)
{
ViewData["Title"] = string.Format("Movies released in {0}", year);
var repository = MvcApplication.GetRepository();
var movies = repository.Medias
.OfType<Movie>()
.Where(m => m.Year == year);
return View("Index", movies);
}
I'd like to access this action with the following URL : /Movie/ByYear/{year}, but the only valid route for this action is this : /Movie/ByYear?year={year}.
I tried to add new routes in my application's RegisterRoutes method, but I can't find a way to get the desired result...
Could anyone tell me how to achieve that ?
Note: this is actually very similar to this question, but no answer was accepted, and the highest voted answer makes no sense to me as I'm completely new to MVC...
Change the name of your parameter year to id and this will match the default route that MVC adds to your project.
So for further clarification, let's take a look at the default route added by ASP.NET MVC:
routes.MapRoute(
"default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
In this route you can see three tokens that are named specifically for controller, action, and the third token which is passed to the action is id. When a request comes into your application, ASP.NET MVC will analyze the routes that are currently mapped and try to find a method signature that matches them by using reflection against your controllers.
When it looks at your Movie controller, it sees an action called ByYear, however that method takes an integer called year, not id. This is why you end up with something like /Movie/ByYear?year={year} when you create an ActionLink for that particular Action. So to fix this, you have two options:
The first and most simple method to fix this is to just change the method signature for your Action to accept a parameter named id which is what I recommended above. This will work fine, but I can see where it might cause a little bit of confusion when you go back to that source later and wonder why you called that parameter id.
The second method is to add another route that matches that method signature. To do this, you should open your Global.asax and just add the following (untested, but should work):
routes.MapRoute(
"MoviesByYear",
"Movies/ByYear/{year}",
new { controller = "Movie", action = "ByYear" }
);
This route is hard-coded, yes, but it won't break the other routes in your system, and it will allow you to call the method parameter year.
EDIT 2: Another thing to note is that the routing engine will stop on the first route it finds that matches your request, so any custom routes like this should be added before the default route so you are sure they will be found.
OK, I just found out how to do it. I just had to create the new route before the default route... I didn't think the order had any significance
routes.MapRoute(
"MovieByYear", // Route name
"Movie/ByYear/{year}", // URL with parameters
new { controller = "Movie", action = "ByYear" } // Parameter defaults
);
EDIT: Isn't there a simpler way ? (not involving renaming the parameters). I'd like to be able to do something like that :
[Route("/Movie/ByYear/{year}")]
public ActionResult ByYear(int year)
{
...
Design considerations aside, if you did not want to rename the parameter, you could add something like the route below, which enforces having the year parameter
routes.MapRoute(
"MovieByYear", // Route name
"Movie/ByYear/{year}", // URL with parameters
new { controller = "Movie", action = "ByYear" },
new { year = #"\d+" } // Parameter defaults
);

Categories