Accessing route URLs in the controller in ASP.Net MVC - asp.net-mvc

ASP.Net MVC has some really nice features for making sure that you have the correct URL for the route you want. So I can use the HtmlHelper class you get the correct URL for my views:-
#Html.RouteLink("Link Text", new {controller = "articles", action = "tag"})
Now this is great. However, I find myself in the situation that I want to know the URL but I am not writing it into a view. So my question is what is the best way to get this information in the controller? I have read various posts that show you how to sneakily create an instance of HtmlHelper but there must be a more straightforward way of doing this.
Thanks.

You can try the UrlHelper.RouteUrl. UrlHelper is accessible via the Url property on controller.

Controller has access to all information about the request, so Request object is where you can find the Url
Request.Url.ToString()

Related

Asp.net MVC redirect Url to another controller view

I am very new to MVC and trying to migrate asp.net application to MVC. Basically I am trying to reuse the code where ever possible. In one case I was trying to use Redirect("SomeUrl") and it works pretty well with the view under same controller.
For eg., I added below piece of code in HomeController.cs
public ActionResult Login()
{
return Redirect("HomeMgr?Section=home&Type=Mgr");
}
Well, could someone suggest me if I can use Redirect(Url) to redirect to a view in another Controller? is there any format for Url something like
"~/controllername/Viewname?something=something&something=otherthing"
(I've read in other posts that I can achieve this using RedirectToAction, but I am trying not to change existing code which uses querystring values. )
Don't use Redirect to redirect to Actions in your app. There are several reasons for this. First, it's just simpler to user RedirectToAction as Alundra's answer provides. However, simpler is only part of the answer.
There's a problem with using Redirect. And that has to do with the way Routing works in MVC. In MVC, you can reach the same action via multiple different URL's. For instance, in a default MVC template, the following are all valid URL's.
http://yoursite/
http://yoursite/Home
http://yoursite/Home/Index
Now, what happens when you use Redirect? If you use the last url, it will work fine. You'll end up with the following url.
http://yoursite/Home/HomeMgr?Section=home&Type=Mgr
But if you're at any of the others, you have a problem...
http://yoursite/HomeMgr?Section=home&Type=Mgr
Oops... that won't work... That will be looking for a controller named HomeMgrController.
You get the same at the root as well.
Using RedirectToAction solves this problem, as it takes your routing into account and will figure out the correct url to redirect you to based on the Controller and Action you specify.
return RedirectToAction("ActionName", "ControllerName", new { Section=home,Type=Mgr ......Anythingelse you want to pass });

Pass relative URL ASP.NET MVC3

I'm trying to pass a list of URL's with Id attributes from a controller to a view.
I can pass a <a href=...> link back but I don't think writing a 'localhost' absolute path is a clean way of approaching this. I cant pass an ActionLink back as it returns the full string. Is ther a simple solution to this problem? Thanks in advance.
Using this overload of the UrlHelper.Action() method and Request object you can get a complete URL including the route parameters such as IDs and the actual hostname of the application.
string url = Url.Action("action", "controller",
new System.Web.Routing.RouteValueDictionary(new { id = id }),
"http", Request.Url.Host);
UrlHelper is available in the controller via its Url property.
You can then pass such URL into your view.
It is also possible to use UrlHelper directly inside your view to create URLs for controller actions. Depends if you really need to create them inside the controller.
Edit in response to comments:
Wherever you need to place the URLs, this "URL builder" you are looking for is still the UrlHelper. You just need to pass it (or the generated URLs) where you need it, being it inside the controller, view or custom helper.
To get the links inside the unsorted list HTML structure you mention, you need to put anchors inside the list items like this:
<ul>
<li>Link</li>
...
</ul>
Then again you just need to get the URLs from somewhere and that would be from UrlHelper.
Simple and easy.
text
the route id = the parameter that is going to be inserted into your method.
eg.
function Details(int id) {
//id has the value of my_var_id
}

ASP.Net MVC redirecttoaction not passing action name in url

I have a simple create action to receive post form data, save to db and redirect to list view.
The problem is, after redirecttoaction result excutes, the url on my browser lost the action section. Which it should be "http://{hotsname}/Product/List" but comes out as "http://{hotsname}/Product/".
Below is my code:
[HttpPost]
public ActionResult Create(VEmployee model, FormCollection fc)
{
var facility = FacilityFactory.GetEmployeeFacility();
var avatar = Request.Files["Avatar"].InputStream;
var newModel = facility.Save(model, avatar);
return RedirectToAction("List");
}
The page can correctly render list view content, but since some links in this view page use relative url, the functions are interrupted. I am now using return Redirect("/Employee/List") to force the url. But I just wonder why the action name is missing. I use MVC3 and .Net framwork 4.
I am new to ASP.Net MVC, thanks for help.
Your route table definitely says that "List" action is default, so when you redirect to it as RedirectToAction("List") - routing ommits the action because it is default.
Now if you remove the default value from your routes - RedirectToAction will produce a correct (for your case) Url, but you'll have to double check elsewhere that you are not relying on List being a default action.
Well, Chris,
If you get the right content on http://{hotsname}/Product/ then it seems that routing make that URL point to List either indirectly (using pattern like {controller}/{action}) and something wrong happens when resolving URL from route or {action} parameter is just set wth default value List. Both URLs can point to the same action but the routing engine somehow takes the route without explicit action name.
You should check:
Order in which you define your routes
How many routes can possibly lead to EmployeeController.List()
Which one of those routes has the most priority
Default values for your routes
Just make the route with explicit values: employee/list to point to your List action and make sure that is the route to select when generating links (it should be most specific route if possible).
It would be nice if you provide your routes mappings here.
but since some links in this view
page use relative url, the functions
are interrupted.
Why do you make it that way? Why not generate all the links through routing engine?
When using the overload RedirectToAction("Action") you need to be specifying an action that is in the same controller. Since you are calling an action in a different controller, you need to specify the action with the alternate overload e.g. RedirectToAction("List", "Employee").

ASP.NET MVC create absolute url from c# code

How do i generate an absolute url from the c# code?
I want to generate a url like this: localhost/{controller}/{action}/{id}. Is there a way to do it in c# like how it can be done in the views?
It wont be generated inside the controller but inside a ViewModel.
string absUrl = Url.Action("Index", "Products", null, Request.Url.Scheme);
Just add Request.Url.Scheme. What this does is add a protocol to the url which forces it to generate an absolute URL.
Check out a similar question Using html actionlink and URL action from inside controller. Seems to be similar and reusable for your requirements.
If you don't want to "build" the url and just want the full path of the current page, this will do the trick
Context.Server.UrlEncode(Context.Request.Url.AbsoluteUri)
I know it's not as elegant as an Extension Method but thought of sharing it for educational purposes
As of latest update to MVC you can use below overload for Url.Action
string url=Url.Action("ActionName", "Controller",
new RouteValueDictionary(new { id= someid }),
//url param
HttpContext.Request.Url.Scheme,
HttpContext.Request.Url.Host);
which generates
http://localhost:port/Controller/ActionName?id=someid

ASP.NET MVC routing

Up until now I've been able to get away with using the default routing that came with ASP.NET MVC. Unfortunately, now that I'm branching out into more complex routes, I'm struggling to wrap my head around how to get this to work.
A simple example I'm trying to get is to have the path /User/{UserID}/Items to map to the User controller's Items function. Can anyone tell me what I'm doing wrong with my routing here?
routes.MapRoute("UserItems", "User/{UserID}/Items",
new {controller = "User", action = "Items"});
And on my aspx page
Html.ActionLink("Items", "UserItems", new { UserID = 1 })
Going by the MVC Preview 4 code I have in front of me the overload for Html.ActionLink() you are using is this one:
public string ActionLink(string linkText, string actionName, object values);
Note how the second parameter is the actionName not the routeName.
As such, try:
Html.ActionLink("Items", "Items", new { UserID = 1 })
Alternatively, try:
Items
Can you post more information? What URL is the aspx page generating in the link? It could be because of the order of your routes definition. I think you need your route to be declared before the default route.
Firstly start with looking at what URL it generates and checking it with Phil Haack's route debug library. It will clear lots of things up.
If you're having a bunch of routes you might want to consider naming your routes and using named routing. It will make your intent more clear when you re-visit your code and it can potentially improve parsing speed.
Furthermore (and this is purely a personal opinion) I like to generate my links somewhere at the start of the page in strings and then put those strings in my HTML. It's a tiny overhead but makes the code much more readable in my opinion. Furthermore if you have or repeated links, you have to generate them only once.
I prefer to put
<% string action = Url.RouteUrl("NamedRoute", new
{ controller="User",
action="Items",
UserID=1});%>
and later on write
link
Html.ActionLink("Items", "User", new { UserID = 1 })

Resources