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.
Related
I've created custom route to support canonical url. It works on the local system. However when I tested my code onto server the bundle created a link but couldn't render the css and js.
Here's the code
routes.MapRoute
(
"Custom",
"{*catchAll}",
new { controller = "Search", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new CustomRouteForSlugs();
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
The link it created on the production link is:
<link href="/Content/css?v=WMr-pvK-ldSbNXHT-cT0d9QF2pqi7sqz_4MtKl04wlw1" rel="stylesheet">
<script src="/bundles/modernizr?v=rGcoDow97GYrNMSwHq7xCCjlcB3UIY4_OhPRc6BBSQA1"></script>
While checking it over the firebug, I'd seen no script or js code attached to it. Putting back a link to static file for css or js works.
How can this issue be solved?
I'm using Fancybox 1.3.4 with ASP.NET MVC 3.
I have following link :
<a id="various" href="Like/List/#feed.Id" class="petlikeCount liked">#feed.LikeCount</a>
and also jquery :
<script type="text/javascript">
$(document).ready(function () {
$("#various").fancybox({
type: 'ajax'
});
});
</script>
Controller action in Like controller :
public JsonResult List(int id)
{
return Json("success", JsonRequestBehavior.AllowGet);
}
My problem is that Like/List is never called (checked with the breakpoint) and fancybox just appears and show content of "parent" page....
I also tried with iframe content returning pure html back, but I'm getting same strange behavior as above.
Thank you in advance!
I'd recommend you using HTML helpers instead of hardcoding anchors:
#Html.ActionLink(
feed.LikeCount,
"List",
"Like",
new { id = feed.Id },
new { id = "various", #class = "petlikeCount liked" }
)
Another thing that you should make sure is that the feed.Id is actually an integer variable so that when the List action is invoked it is correctly passed this id.
So your url should look something like this: /List/Like/123. And then assuming tat you have kept the default route and haven't messed up with some custom routes, the List action should be called and passed the correct id as argument.
Also I would very strongly recommend you using a javascript debugging tool in your browser such as FireBug in which you will be able to see any potential errors with your scripts as well as the actual AJAX requests being sent which will allow you to more easily debug such problems.
In the application I am working on, I have an Html page inside views folder and I have mentioned the action as follows.
<form name="form" onsubmit="return validateForm();" method="post" action="//Controllers/RegistrationController.cs">
The registration controller returns a view.
public ActionResult Detail(string name)
{
return View();
}
When I run the program, I get server not found error.
I also tried changing the action string to action="//Controllers/RegistrationController.cs/Detail"
but got the same error.
Does the action string have to be written in some other way?
Thank you very much in advance for your help.
Assuming you are using the default routes ({controller}/{action}/{id}) you need:
action="/Registration/Detail"
Actually I would recommend you using HTML helpers to generate forms and never hardcode them as you did:
#using (Html.BeginForm("Details", "Registration", FormMethod.Post, new { name = "form", onsubmit = "return validateForm();" }))
{
...
}
Description
You don't have to set the path like in your solution. You don't need to set Controllers because the framework knows that you mean the controller.
Assuming that you dont change the routing in global.asax, your RegistrationController.cs has an ActionMethod called Detail (decorated with [HttpPost]) and the following folder structure within your project.
Controllers/RegistrationController.cs
Views/Registration/Detail.cshtml
#using (Html.BeginForm("Detail", "Registration", FormMethod.Post, new { #onSubmit = "return validateForm();" }))
{
// Your Form's content
}
/registration/detail - you don't need to reference the path to the actual file. The framework finds the controller class and invokes the requested action for you. It uses the routes as defined in global.asax.cs to determine the controller and action from the url. The default route is {controller}/{action}/{id} where the first two have defaults of "Home" and "Index", respectively, and the third is optional. You can change this if you want by adding/modifying the route set up.
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.
My first post...
When I use RedirectToAction the url in the browser doesn't change. How can I achieve this?
I'm switching over to ASP.NET MVC 3.0 (also using jQuery Mobile) after 10+ years using web forms. I'm about 8 weeks into it, and after several books and scouring Google for an answer, I'm coming up dry.
I have a single route defined in Global.asax:
routes.MapRoute(
"Routes",
"{controller}/{action}/{id}",
new { controller = "Shopping", action = "Index", id = UrlParameter.Optional }
I have a ShoppingController with these actions:
public ActionResult Cart() {...}
public ActionResult Products(string externalId) {...}
[HttpPost]
public ActionResult Products(List<ProductModel> productModels)
{
// do stuff
return RedirectToAction("Cart");
}
The url when I do a get and post (with the post having the RedirectToAction) is always:
/Shopping/Products?ExternalId=GenAdmin
After the post and RedirectToAction I want the url in the browser to change to:
/Shopping/Cart
I've tried Redirect, and RedirectToRoute but get the same results.
Any help would be greatly appreciated.
[Update]
I found that jQuery Mobile AJAX posts are the culprit here. If I turn off jQuery Mobile's AJAX it works.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script type="text/javascript">
// do not handle links via ajax by default
$(document).bind("mobileinit", function () { $.mobile.ajaxEnabled = false; });
</script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0rc2/jquery.mobile-1.0rc2.min.css" />
The ordering of the above scripts is important. I had to include the script to jQuery first, then include the script to disable jQuery Mobile's use of AJAX and then include the script to jQuery Mobile.
I'd still like to find a way to use AJAX and have the url update properly. Or at the least be able to call jQuery Mobile's "loading" message (or bake my own).
I think I've found an answer. Buried deep in the jQuery Mobile documentation, there is information about setting the data-url on the div with data-role="page". When I do this, I get the nice jQuery Mobile AJAX stuff (page loading message, page transitions) AND I get the url in the browser updated correctly.
Essentially, this is how I'm doing it...
[HttpPost]
public ActionResult Products(...)
{
// ... add products to cart
TempData["DataUrl"] = "data-url=\"/Cart\"";
return RedirectToAction("Index", "Cart");
}
Then on my layout page I have this....
<div data-role="page" data-theme="c" #TempData["DataUrl"]>
On my HttpPost actions I now set the TempData["DataUrl"] so for those pages it gets set and is populated on the layout page. "Get" actions don't set the TempData["DataUrl"] so it doesn't get populated on the layout page in those situtations.
The only thing that doesn't quite work with this, is when you right-click... view source... in the browser, the html isn't always for the page you are on, which isn't unusual for AJAX.
Not sure if it is still actual, but in my case I wrote following helper method
public static IHtmlString GetPageUrl<TModel>(this HtmlHelper<TModel> htmlHelper, ViewContext viewContext)
{
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.Append("data-url='");
urlBuilder.Append(viewContext.HttpContext.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped));
urlBuilder.Append("'");
return htmlHelper.Raw(urlBuilder.ToString());
}
And then use it as follows:
<div data-role="page" data-theme="d" #Html.GetPageUrl(ViewContext) >
This way I don't need for every redirect action store a TempData. Worked for me fine both for Redirect and RedirectToAction. This would not work properly in case if you use method "View()" inside controller and return different view name, which will change UI, but will retain url.
Hope it helps
Artem
David, this was a big help to me. I just wanted to add that in my case I had to use the following format to get the Url to display in the correct form as my other url's:
TempData["DataUrl"] = "data-url=/appName/controller/action";
return RedirectToAction("action", "controller");
As a side note, I also found that when assigning the value to TempData["DataUrl"] I was able to leave out the escaped quotes and enter it exactly as above and it seems to be working fine for me. Thanks again for your help.
There is an issue on github
https://github.com/jquery/jquery-mobile/issues/1571
It has a nice solution without the need of TempData