Parameters after url Asp net mvc - c#

I would like to have some paramaters after my website's URl.
So, mysite.com/ThisIsMyStringMessage, would show this :
Hello, ThisIsMyStringMessage.
Of course, the view related to the action contains this :
Hello, #ViewBag.Message
And the HomeController :
public ActionResult Index(string message)
{
ViewBag.Message = message;
return View();
}
Edit related to comments :
#Zim, I'll have more than one controller.
#Jessee, So that's what I'm doing here, thank you, I didn't know really what I was doing.

With the default routing, ThisIsMyStringMessage will be picked up as the Controller, not as an Action method parameter. You will need a custom route to be able to do this. Try the following before the default route in Global.asax:
routes.MapRoute(
"RootWithParameter",
"{message}",
new { controller = "Home", action = "Index", message = UrlParameter.Optional }
);
Alternatively, access the method with mysite.com?message=ThisIsMyStringMessage

You will need to take a look at your RouteConfig.cs or Global.asax to setup a route with the parameter of message instead of id. Right now it probably looks like:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
You would need to change the url parameter to something like {controller}/{action}/{message} for that to work.
Also, be careful with passing strings in the URL. ASP.NET (and some modern browsers) gives you many security protections to prevent people from doing nasty stuff like XSS, but it's probably not a habit you want to create.

Related

C# ASP:NET MVC back end - Change from React Router v4 HashRouter to BrowserRouter results in 404 on refresh

I'm currently using HashRouter and it works really well. However I would like to be able to use the # on sub routes as well for linking to paragraphs. For example /details#Summary. As a benefit I will also get cleaner URLs and if needed I can get some SEO.
Works and gives correct results on refresh/direct link.
<HashRouter>
<App />
</HashRouter>
Works but gives 404 on refresh/direct link.
<BrowserRouter>
<App />
</BrowserRouter>
I understand that the problem here is my routing in .Net and I need to change it. What do I need to do? I have a default route but it does not get hit.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
First remove the standard routes.MapRoute that is shown above and then add this:
routes.MapRoute("Client", "{*anything}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Now any route will render your default action.
Optional:
If you have a controller with attribute routing, example:
[RoutePrefix("Home")]
public HomeController : Controller {
//GET Home/Index
[HttpGet]
[Route("Index")]
public ActionResult Index() {
return View();
}
}
You also need to add:
routes.MapMvcAttributeRoutes();
The thing is that when you change that, asp.net keeps trying to match a route from for details.
What you need to do is create a route that matches all paths, so that it returns the default one, eg: home/index
This is the route I use:
routes.MapRoute(
"Default",
"{*url}",
new { controller = "Home", action = "Index" });
That will give control to the browser to math the paths after '/'

Parameters in MVC not being correctly passed into the view from routing

I'm teaching myself MVC and have an issue with routing correctly
I have a controller named "ClipsController" and 1 view inside with the name "Index" (boring, i know)
I have my routeconfig file configured with the following route:
routes.MapRoute(
"Clips",
"Clips/{id}",
new { controller = "Clips", action = "Index", id = urlparameters.Optional }
);
which is Before the "Default" route. When i go to /Clips/ExampleID
it does hit the correct route, and does start the Index action in the Clips controller. What i'm having trouble with is the parameter 'ID' fails to pass through into the Index page, but i end up on the index action of the Clips controller, with the URL domain.my/Clips/ExampleID
I attempt to get the ID parameter with
httpcontext.current.request.querystring["id"]
which always returns a null. My actionresult in the controller is as follows:
public ActionResult Index(string id)
{
return view()
}
To reiterate, I'm not able to see the querystring id on the index view, even though the URL does the correct route, and the actionresult in the controller is to my kowledge correct. If i have done something critically wrong or you need more information please let me know, Thanks.
I attempt to get the ID parameter with
httpcontext.current.request.querystring["id"]
No, you don't have any query string parameters in this url:
http://domain.my/Clips/ExampleID
Query string parameters follow the ? character in an url. For example if you had the following url:
http://domain.my/Clips?id=ExampleID
then you could attempt to read the id query string parameter using your initial code.
With this url: http://domain.my/Clips/ExampleID you could query the id route value parameter. But using HttpContext.Current is absolutely the wrong way to do it. You should never use HttpContext.Current in an ASP.NET MVC application. Quite on the contrary, you can access this information everywhere where you have access to HttpContextBase (which is pretty much everywhere in the ASP.NET MVC application pipeline):
httpContext.Request.RequestContext.RouteData.Values["id"]
Long story short, if you needed to query the value of this parameter inside your controller action you would simply use the provided id argument:
public ActionResult Index(string id)
{
// Here the id argument will map to ExampleID
return view()
}
Also you probably don't need your custom route:
routes.MapRoute(
"Clips",
"Clips/{id}",
new { controller = "Clips", action = "Index", id = urlparameters.Optional }
);
That's completely redundant and it is already covered by the default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
So feel more than free to get rid of your custom route.

ActionLink doesn't generate proper routing url for actions which has two parameters

In the view
#Html.ActionLink("Edit", "Edit", new { id = 1, year = 1 })
In the controller
// GET: /Forecasts/Edit/5
public ActionResult Edit(int id, short year)
{
...
}
It generated a url like
http://<localhost>/controllername/actionname/1?year=1
I would expect the actionlink generate a URL like :
http://<localhost>/controllername/actionname/?id=1&year=1
This url cannot be interpreted by MVC default routing, why the URL is not generated in the expected way? Thanks.
Update:
Now I found out it was a typo caused this problem for me, but the answer below is still good enough as it help me to further understand the way route works
You are using the default route, which will be formatted like this:
"{controller}/{action}/{id}"
Which means the first parameter will be id and will be written just after the /, without any named GET parameter.
If you want to have explicit parameters everywhere, just use this route configuration:
"{controller}/{action}"
If you remove the id all your parameters will be named.
I would expect the actionlink generate a URL like : http://<localhost>/controllername/actionname/?id=1&year=1
You cannot expect something like this if you are using the default route:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Get rid of the {id} from the if you expect such url pattern:
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index" }
);

MVC routing vs. partial class

I have a request controller that is getting out of hand, and I want to divide the actions on several controllers while maintaining a clean URL. I'm trying to experiment with routing, but without success. I've read some examples and tutorials on routing, but, though I understand the examples, nothing seems to apply to my case, and I feel non the wiser. What I want is for the URL Requests/Approval to be handled on my ApprovalController instead of my RequestController, so I wrote the following.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Approval",
"Request/{controller}/{action}",
new { controller = "Approval", action="Index", id = "" }
);
}
But it's not working. Why? I have a folder in the my Views called Approval, and in there I have a file called Index.cshtml. How should I code the MapRoute?
Edit
I added all the routes I've got
You need to swap the two MapRoute statements, like so:
routes.MapRoute(
"Approval",
"Request/Approval/{action}",
new { controller = "Approval", action="Index", id = "" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
The reason it is currently not working is because the first statement ('Default' route name) is getting matched before the second one is even evaluated.
In addition (as noted in my above example,) you need to remove '{controller}' in the Approval route and replace with 'Approval'... unless you specifically want the URL /Request/{ANY controller}/{action} to go through, which I doubt. From your question it seems you only want /Request/Approval/ to go to your Approval controller.
Don't forget to keep the Default route at the bottom, so as to match your other controllers and actions. It serves as a catch-all should no other matches exist.
The order you map your routes matters. Move the second route before the default route.
You will still have a problem though, as any thing /request/something will look for the SomethingContoller. To fix this, change your route to this:
routes.MapRoute(
"Approval",
"Request/Approval/{action}",
new { controller = "Approval", action="Index", id = "" }
);

Problems understand Routing in MVC

I thought I had at least a bases for understanding routing in MVC after all the documentation I have read, only to fail at it when attempting to utilize it.
I have the following two routes declared in my Global.aspx
routes.MapRoute(
"", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Admin", action = "List", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
I have a AdminController that I have a few methods, one that is "List" method that renders a list of products to a "List" view.
I thought I understood how RedirectToAction works, and I added an "Add" method (see below) that adds a new Product and returns a RedirectToAction which I understood would be the proper way to redirect to the List action on the same "AdminController"
[HttpPost]
public ActionResult Add(Product product) {
if (_prodRepo.Add(product)) {
return RedirectToAction("List", "Admin");
}
return View("Add", product);
}
However, on the return of the "Add" it always attempts to route to the path website.com/Account/Login/ReturnUrl=%2f.
However, if I go to website.com/Admin it does render the list as I expect. But when using the RedirectToAction as in the example above, it attempts to go to the /Account/Login (Controller/action).
It was my understanding that the RedirectToAction("List", "Admin") would route to the "List" method on the AdminController controller and that I was using it as expected.
Can someone please help me understand the reasoning behind this. But also, could someone post some recommended articles for understanding the whole MVC routing including how the web.config works with routing.
Finally, it was also my understanding that route discovery by the framework is done in the order they are specified in your routes.MapRoute() declaration and stops at the first one that matches. Therefore, if the first one is listed as Controller = "Admin", Action = "List", I would expect by convention that this is the correct route it would first match and return.
Your routes need to be different (the url parameter) since the first route with a matching url will be used.
This will therefore work for you:
routes.MapRoute("Admin",
"admin/{action}/{id}",
new { controller = "Admin", action = "List", id = UrlParameter.Optional });
The defaults (third parameter in the method) are used if the parameters isn't found/specified in the uri.
As for your question regarding /Account/Login/ReturnUrl=%2f. The login redirections are handled by the MembershipProvider and not by the standard routing mechanism.

Categories

Resources