Url.Action doesn't give me the correct path - asp.net-mvc-3

In my view I have the following code...
<script type="text/javascript">
var url = '#Url.Action("Index", "Home")';
</script>
The problem it emits simply...
<script type="text/javascript">
var url = '/';
</script>
Can someone tell me what is wrong with this?

It is not wrong. That's because Index and Home are the default (I think so if you just started), so MVC knows automatically that no URL is needed.
If you call /Home/Index it's the same as you call /.
You can see your default routes in your global.asax under RegisterRoutes.

This is expected, the default routing configuration is configured to use the Home controller and the Index action by default.
See the RegisterRoutes method in your HttpApplication type:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // parameter defaults
);
If you link to a parameter value which is configured as a default, MVC will avoid rendering it in the output, as it isn't required.

Related

Changing Route Config impact on ajax url and embedding controller name in request (Mulitple Time)

My all ajax calls unexpectedly appending controller name twice in ajax calls by changing following line
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
to
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
);
I changed this line because i found a extra redirect, that first user will go to home and then from there he will be redirected to login page due to authorization failure. have a look at following console error
http://localhost:51381/Document/Document/GetCategoriesByDocumentType?categoryDocumentType=1&_=1480570187959
404 (Not Found)
as you can see that two controller name was appended.
/Document/Document/
My ajax call in separate Js file.
var url = 'Document/GetDocumentGrid?CategoryDocumentType=' +
CategoryDocumentType + '&categoryId=' + CategoryList + '&keywords=' +
search + '&isArchived=' + isArchived;
and when i revert route config , all ajax call works as expected.
what if i wanted my user to go on login page directly, instead of home? or i have to change all my ajax URL's ? And what is the reason of this behavior?
Note: i cannot use any Razor syntax as i have separate js files and i dont want to change every Js file, as my project goes almost 90 pages :(

#Url.Content changes after publishing

In My MVC3 Razor application I'm referring ajax in Layout page as
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
When I run this in my local machine,its working perfectly.. However after publishing using iis7, my ajax calls are not working. When i checked the View Source in browser, the reference is like <script src="/Scripts/jquery.unobtrusive-ajax.js" type="text/javascript"></script> before publishing and <script src="mvcapplication/Scripts/jquery.unobtrusive-ajax.js" type="text/javascript"></script>
after publishing. I'm confused Why url gets changed ?
Url.Content(string contentPaht) uses the VirtualPathUtility.ToAbsolute(string contentPath) method to create an absolute url:
public string Content(string contentPath)
{
if (string.IsNullOrEmpty(contentPath))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "contentPath");
}
if (contentPath[0] == '~')
{
return VirtualPathUtility.ToAbsolute(contentPath,
this.RequestContext.HttpContext.Request.ApplicationPath);
}
return contentPath;
}
As you can see the Request.ApplicationPath is used, which respresents the the Virtual Directory.
When the argument contentPath does not start with a ~ it returns the contentPath without using the ToAbsolute(string contentPath) method.
So you can try using:
#Url.Content("/Scripts/jquery.unobtrusive-ajax.js")
Edit: You can also try to change the default route:
routes.MapRoute(
"Default",
"NameVirtualDirectory/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Because on the server the application has the virtual path "mvcapplication", that is the app resides in IIS in the virtual directory "mvcapplication". It has nothing to do with asp.net mvc, it's an IIS setting.

Why #Html.ActionLink("Home", "Index", "home") generates Home

When I use Html.ActionLink, I found that #Html.ActionLink("Home", "Index", "home") generates this string Home, so why the address \home\index becomes \, I found this is related with default route which setted in web.conf. I have viewed the mvc 3 source code, but I can't find answer. Who can help me? Thanks.
That's due to the default route. If you don't specify default action and controller it will generate /home/index as url.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { id = UrlParameter.Optional }
);
routing is bidirectional:
- in: it converts incoming urls into controller/actions/parameters
- out: it converts controller/actions/parameters into urls

MVC3 routes interfering with JS paths

I have the following route defined:
routes.MapRoute(name: "StateResults", url: "{state}/{searchTerm}", defaults: new { controller = "Results", action = "SearchState" });
In one of my shared chtml files I have the following defined:
<script src="#Url.Content("Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
I understand why the JS is not getting loaded, but how do I get around this? I get around this?
Thanks.
You can ignore routes for JS
IgnoreRoute("{file}.js");
As an alternative method you can use the constraint parameter to avoid files ending with js
routes.MapRoute("StateResults", "{state}/{searchTerm}",
new { controller = "Results", action = "SearchState" },
new { searchTerm = #".*?([^js])$" }); // regex not tested
RouteCollectionExtensions.MapRoute Method (RouteCollection, String, String, Object, Object) from MSDN
constraints
Type: System.Object
A set of expressions that specify values for the url parameter.
you need to set up the routes that it ignores .js files.
a good description is found here:
http://weblogs.asp.net/rashid/archive/2009/04/03/asp-net-mvc-best-practices-part-2.aspx
something like this will do the trick:
routes.IgnoreRoute("{file}.js");

Url.Action to show page no in url

Trying like this
Url.Action("Index", "Home", new { page = 5 })
is giving me url like
/Home/Index?page=5
How to get a url like this
/Home/Index/5
By defining a route:
routes.MapRoute(
"PagedRoute",
"{controller}/{action}/{page}",
new { controller = "Home", action = "Index", page = UrlParameter.Optional }
);
And be careful with the default route (the one that uses an id) as it is similar. You will might need to put this custom route before the default one or remove the default route as it rarely be hit under those circumstances.
I would recommend you going through the Routing tutorials to gather deeper understanding of how they work.

Resources