URL Handling + MVC 4 + Jquery Ajax + IIS - asp.net-mvc

I've been developing an MVC 4 application that also includes Ajax via Jquery.
And I got a problem.
For example if I click a button, the onclick event fires a javascript method. This method is in a .js File.
That javascript method uses Ajax to call an ActionResult which receives some parameters (string, int) nothing special. So.. lets say my Action Result is in the "Person" Controller and that its name is "Add". So I want to add a Person.
My url property in my ajax call should be "/Person/Add" and my data should be something like:
var person = new Object();
person.name = "John";
person.id = 1;
data: person
This works without any problem when running the application with Visual Studio. But when I deploy it in IIS I get a 404 Error.
I've try this. I added a <link> <link id="PersonAddURL" href="Url.Content("~/Person/Add") /> in the layout and then instead of using url: "/Person/Add" I changed it to url: $("#PersonAddURL").attr("href").
This works, now, I dont think is a good way to solve it. There should be another one better. And still even if I managed to solve it, I would like someone to explain me the reason this is happening. I dont like the idea of having one link tag for each Url.
Thanks for the future answers.

What I usually do is have the following global javascript variable in my ASP.NET MVC layout:
<script>var webroot = "#Url.Content("~/")";</script>
then from any JS file you can do the following:
$.post(webroot + "Person/Add", person, function(result){ ... });
just make sure you declare and initialize the webroot variable before any AJAX calls.
If you are using namespaces in your javascript then you could change it to (assuming app namespace):
<script>app.webroot = "#Url.Content("~/")";</script>
and remove the global variable that makes developers uncomfortable.

Related

Undetectable caching

I'm a web app developer with ASP.NET MVC 5 in server-side and AngularJS in client-side. The navigation, in client-side, is managed with module UI-Router. In server-side I've configured my custom authentication and authorization. When I excecute the app can see a navigation bar with many links. In particular, I have a link named "Overview" that redirects to controller Overview.
Code client (html):
<a ui-sref="Overview">Overview</a>
Code client to redirect (angular):
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("Home/Index");
$stateProvider
.state("Overview", {
templateUrl: "Home/Overview",
url: "/overview"
})
Controller code:
[OutputCache(Duration=0, NoStore=true)]
[AllowAnonymous]
public ActionResult Overview()
{
return PartialView();
}
With a breakpoint in line "return PartialView()" to controller code, I can see that controller returns partial view when I click over "overview" in menu app. But when I click second time, the breakpoint does not trigger. I think it's a caching issue.
I have read that caching issue can be generated:
* In server-side.
* In client-side.
* Even IIS.
I have tried many solutions: In server side I use attribute [OutputCache].
When i read in my browser the http headers i can see
In client side i could not find a solution to avoid caching, but i think that UI-Router shouldn't cache anything.
As additional measures I put in my web.config:
<system.webServer>
<caching enabled="false" enableKernelCache="false" />
</system.webServer>
even, I created my own custom ActionFilterAttribute but did not work.
i don't know what else to do.
PS: sorry for my english
If there is any other plugin which does caches its templates, then your solution will clean those templates and make those plugins unusable.. hence your solution is not good.
To solve problem of html caching you should add random query string at the end of html filename... the other solutions you mentioned are for non-caching of api responses and not for static content (html/js/css files)
To add random query string to ur html. either you can use modules like grunt-cache-busting or gulp-rev or use query string as param query-string-cache-busting.
Please note that datetime/file-hash are best cache-busting param
Ok, I've found the solution.
Despite avoid caching from server side with attributes like OutputCache, or avoid caching from IIS setting my web.config, the issue persisted.
AngularJS was the guilty. In other post I found the solution.
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
This solution is provided by Mark Rajcok and Valentyn Shybanov. So thanks to both.

Why moving the code from html into .js causes issue?

I have asp.net mvc project with knockout.js so my index page is getting really huge because of lots of javascript functionality.
I'd love to move js code into a separate file but it does not allow me to apply it to the most of the code because if I have something like
$.ajax({
url: "#Html.Raw(#Url.Action("Load"))",
Then it pops up a error if I move this part of the code into another file.
Please advise how can I resolve this issue?
Javascript files are not parsed by ASP.net, so the variables you have of #Html.Raw and #Url.Action("Load") will never be processed.
As #James Lai noted, server side code isn't parsed as such by ASP.Net. See this post for a workaround, or you can pick and choose which scripts can still stay on the page (with server-side code) instead of the "everything" - your choice as to which approach meets your requirements.
Javascript files are not parsed by ASP.NET MVC, thus #Html.Raw(#Url.Action("Load")) will not work in javascript file.
Heres workaround
Instead declare a variable in view.cshtml. In script section as
<script type="text/javascript">
var actionUrl = '#Url.Action("Load", "Controller")';
</script>
And use actionUrl in javascript file.

Backbone With Rails

I'm getting my data from a service and then setting the data to my bean object and want to using the same data in my view displaying it in a form in rails view now. Now I want to validate this form using backbone.
I'm new to both Rails and Backbone.
Kindly give me an idea on how to proceed on this.
I think perhaps you are confused about how web applications work. Backbone is a client-side framework; it uses Javascript code that is run in your users' browsers. Rails is a server-side framework; it uses Ruby code that runs on your server.
Given all that, your Backbone code and your Rails code by definition have to be completely separate. The two can communicate in only two ways:
1) Your Rails code can write <script> tags to the page (inside a .html.erb file) and put variable data there; for instance:
<script>
var myVarFromRails = '<%= someRailsVariable %>';
</script>
When that comes back from the server (ie. when you view source the page) that will get converted to:
<script>
var myVarFromRails = 'foo';
</script>
(assuming 'foo' was the value of someRailsVariable).
2) Your Javacript code can make AJAX requests to Rails URLs, and whatever the Rails code spits out there will come back as the response to your AJAX request. In other words you can do:
$.ajax({url: someRailsUrl, complete: function(response) {
// whatever the server sent back will be inside the "response" variable
}});
Other than that the two are pretty much entirely separate, and if you want to do the same thing in both of them (eg. validate a form) you essentially have to write the code twice, once for Ruby and once for Javascript.
I say "essentially" because there are Rails plug-ins which do #1 and #2 for you in different ways. I'm not a Rails expert, and even if I was there are so many of these plug-ins that you really need to look for yourself to find out what exists and what makes sense for your codebase.
Hope that helps.
* EDIT *
I know I just said I wouldn't list libraries, but then I realized it'd be more helpful if I at least provided a few to get you started. Just don't take these as canon; they're simply some popular libraries at the moment, but they may or may not be right for you.
https://github.com/codebrew/backbone-rails
https://github.com/meleyal/backbone-on-rails
https://github.com/aflatter/backbone-rails
https://learn.thoughtbot.com/products/1-backbone-js-on-rails
http://kiranb.scripts.mit.edu/backbone-slides/
That last two aren't actually libraries, they're a book/presentation, but I thought they might be useful.

Redirect from within an Ajax form post

I have an action method that depending on some conditions needs to return a partial view via ajax, or redirect to another Controller/Action. The correct view is returned but it is placing it in the Ajax forms UpdateTargetId rather than redirecting to a completely new page. Anyone have any idea how I can accomplish this?
I think I would refactor this to use jQuery rather than MVC Ajax. jQuery will give you a lot more control over what you can do with the result that you get back. If that's not an option, you might want to look at the OnComplete callback and see what data you get passed to it and see if there is a way get the url that you want to be redirected to from it.
Also, I seem to remember that if you return a JavaScriptResult it will execute it regardless of how the AJAX was invoked. You might want to try something like:
return JavaScript( "window.top.location.href ='" + Url.Action( "Action" ) + "';" );
May be this link could help to solve your problem, and insert your javascript to change current page to other controller, for example
window.location = 'controller/action';

Using JQuery with ASP.NET MVC Framework

I have searched the forum, and google for this topic. Most of the articles are talking about using JSON to call the controller/action on the server and do ajax effect on the result.
I am trying to use some very basic JQuery features, like the JQuery UI/Tabs, and JQuery UI/Block for a dialog window. I cannot get these simple samples to work in my MVC project. Any ideas how I should modify these samples? I only need these basic feature now and I can go from here.
Thanks!
Actually I just got it working. The problem is that I need to modify the path to an absolute path to the view page because the relative path doesn't work with the MVC routes {controller}/{action}/{id}.
Thanks!
For info, re the relative path issue - I discussed this here (the same concept applies to any page, not just master pages). The approach I used is like so:
1: declare an extension method for adding scripts:
public static string Script(this HtmlHelper html, string path)
{
var filePath = VirtualPathUtility.ToAbsolute(path);
return "<script type=\"text/javascript\" src=\"" + filePath + "\"></script>";
}
2: when needed (for example in the <head>...</head>) use this method:
<%=Html.Script("~/Scripts/jquery-1.2.6.js")%>
The advantage of this is that it will work even if the web app is hosted in a virtual directory (i.e. you can't use "/Scripts" because you aren't necessarily at the site root) - yet it is a lot clearer (and less messy) than the full script with munged src, i.e.
<script ... src="<%=Url.Foo(...)%>"></script>
I just implemented the jquery autocomplete textbox in one of my asp.net project. I only had to import the js file and drop some code into my aspx page. Could you be more detailled about what sample you are trying to run?
This is quick response!!
I am trying to run this "Simple Tabs" on this page:
http://stilbuero.de/jquery/tabs/
I think it is the same with this one: http://docs.jquery.com/UI/Tabs
I just copied and pasted the whole thing into my MVC view page, with corrected path to the jquery.js and .css files, but the content in the tabs all show up together (two of them are supposed to be hidden). My understanding is that this simple jquery plugin just show and hide content.
I had the exact same problem with the jquery thickbox plugin, that the item marked as "hidden" (the dialog box) will always show up in my MVC view page.
I can understand some of the MVC+Jquery+json articles, but I don't understand why the hide/show doesn't work.
Thanks!
I just made a walkthrough on how to do this:
http://blogs.msdn.com/joecar/archive/2009/01/08/autocomplete-with-asp-net-mvc-and-jquery.aspx

Resources