ASP.NET MVC2 Ajax ActionLink calls wrong action - c#

I am trying to change some data on my page using Ajax. This is a piece of code that does it:
<%= Ajax.ActionLink("Rate Up", "RatePost", new { postId = post.Id, rating = 1 }, new AjaxOptions { UpdateTargetId = string.Format("postRating_{0}", count) })%>
The problem is that RatePost action is not called after click on this link. Instead, the parent view action is being called. How can I avoid this and just call the RatePost action with parameters I specified?

The code seems to be correct.
Verify that you included the Microsoft Ajax scripts in your view:
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>" type="text/javascript">/script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcAjax.js") %>" type="text/javascript"></script>
If something fails in the javascript generated by Ajax.ActionLink, the click action is not cancelled.

Related

Controller returning PartialView overwriting entire View

I'm POSTing and trying to re-load a partial view with the new data using Ajax like this:
Index.cshtml
<div id="left-column">
#Html.Partial("~/Views/Project/_ProjectList.cshtml", Model.ProjectList)
</div>
~/Views/Project/_ProjectList.cshtml
#using (Ajax.BeginForm("Create", "Project", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "left-column"
}))
{
<h3>Create a new project</h3>
<div class="form-group">
<label for="new-project-name">Name</label>
<input type="text" class="form-control" id="new-project-name" name="Name" placeholder="Example" />
</div>
<button type="submit" class="btn btn-primary">Create Project</button>
Cancel
}
Then my Controller returns the PartialView after some db work:
[HttpPost]
public PartialViewResult Create(Project newProject)
{
db.Projects.Add(newProject);
db.SaveChanges();
var projectList = db.ProjectLists.SingleOrDefault(pl => pl.Id == 1);
return PartialView("~/Views/Project/_ProjectList.cshtml", projectList);
}
I would expect the _ProjectList partial view to load into the #left-column element with the new projectList passed in by the Controller, but instead, the entire View is being overwritten, so the entire body of the new HTML source looks basically like this:
<body>
<!-- all the stuff from the _ProjectList partial -->
</body>
It's worth noting that after the partial view returns, the URL reads /Project/Create, which I wouldn't expect.
I've included jquery-validate and jquery-validate-unobtrusive, and the console isn't showing any errors, so that shouldn't be the problem.
Any idea what's going on?
When using Ajax.BeginForm helper method to do ajax form posting, you need to include the jquery.unobtrusive-ajax.js file as well. This file has the code to handle the submit button click event and send the form asynchronously rather than doing the normal form submit.
If you do not include this file, the form submit will be normal. My guess is that you missed to include this file and hence missing the ajaxified form submit experience.
So make sure to load this file after jQuery
#Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
Here is the link to nuget page if you want to add this file via nuget package manager.
Benjy got it in a comment above. It was a jQuery version issue. I'm running 3.1.0, and jquery.unobtrusive-ajax stopped working with jQuery version 1.9.

jQuery Click - Doesn't work when page 1st loaded, but works if page is reloaded

I have an issue with the jQuery click function. I am trying to integrate jQuery Mobile Autocomplete into an C# MVC application.
It the following code doesn't work when the page first loads. However, it works if I reload/refresh the page.
HTML:
<ul data-role="listview" class="selectitems" data-filter="true" data-inset="true" data-filter-reveal="true" data-filter-placeholder="Search Ingredients...">
#foreach (var i in Model.ingredientList){
<li data-id="#i.id" data-unit="#i.useUnit.symbol">#i.title</li>
}
</ul>
Script:
<script src="/Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.mobile-1.3.2.min.js" type="text/javascript"></script>
$(document).ready(function () {
$('.selectitems > li').on('click', function () {
$('input[data-type="search"]').val($(this).text());
$("ul:jqmData(role='listview')").children().addClass('ui-screen-hidden');
$('#hdnIngredientID').val($(this).data('id'));
$('#txtUseQtyDetails').val($(this).data('unit'));
$('#hdnIngredientTitle').val($(this).text());
$('#txtQty').focus();
});
$('.ui-input-clear').on('tap', function () {
$('#hdnIngredientID').val('');
$('#txtUseQtyDetails').val('');
});
});
Any assistance would be appreciated.
UPDATE:
jQuery-mobile autocomplete hides the list items until user input happens using CSS "display: none;". Would this prevent the click function from being assigned? If so, how do I work around this?
FURTHER UPDATE:
Found that the "live" function is depreciated. Changed it to "on" instead. Unfortunately this didn't fix the problem :-(
Could it be because the "li" items are hidden by CSS when the page is loaded?
I've deployed it here:
http://rar_mobile_dev.runarestaurant.com/Ingredient/Create?recipe_id=15240
(username: test, password: test)
You could try using on() in stead of click.
$(document).on('click', '.selectitems > li', function(){
$('input[data-type="search"]').val($(this).text());
$("ul:jqmData(role='listview')").children().addClass('ui-screen-hidden');
$('#hdnIngredientID').val($(this).data('id'));
$('#txtUseQtyDetails').val($(this).data('unit'));
$('#hdnIngredientTitle').val($(this).text());
$('#txtQty').focus();
});

JQuery AJAX Post Inside Partial View

In my C# MVC4 application, I have two main views: "Index" and "Index_Perm." The logged-in user's role is what determines which of these views is rendered. "Index" contains a view called "PMain" and Index_Perm" contains a view called "PMain_Lim." "PMain" and "PMain_Lim" contain another partial view called "Analysis." Inside of "Analysis", I have this script:
<script type="text/javascript" charset="utf-8">
$(document).ready(function () {
$('#SubmitAverage').click(function () {
var $form = $('#form1');
$.ajax({
type: "POST",
url: "Home/Average",
data: $form.serialize(),
success: function () {
alert("Edit successful");
},
error: function () {
alert('failure');
}
});
});
});
</script>
My issue is that, when "Index" is the main view being accessed this script runs correctly when the Submit button is clicked. When "Index_Perm" is the main view however, when the button is clicked, the AJAX post fails with the error: The resource you are looking for has been removed, had its name changed, or is temporarily unavailable. The directory or file specified does not exist on the Web server. After some investigation in Firebug, I see that it is trying to access: mylocalhost/Home/Index_Perm/Home/Average instead of: mylocalhost/Home/Average which is specified as the url to send the POST in my script.
Here is the applicable portion of code which is identical in "PMain" and "PMain_Lim" which contains the button that is tied to the script:
<div id="Analysis" title="Analysis">
#Html.Action("Analysis", "Home", Model)
</div>
</section>
<section>
<h3>
<button class="btn" id="SubmitAverage" value ="SubmitAverage" name="action:SubmitAverage" type="button">Submit Averages</button>
</h3>
</section>
<section>
<div id="OtherView" title="OtherView" class="OtherChanges">
#Html.Action("OtherView", "Home", (string)ViewBag.SearchKey)
</div>
</section>
Any ideas why its ignoring what I've specified as the URL to use in the JQuery AJAX POST and/or how to correct it?
Use the urlhelper in your ajax post
url: '#Url.Action("Average","Home")',

"Unknown web method" if ASPX WebMethod function name is altered. Dynamic compilation issue?

I have a standalone .ASPX page (no code behind) which holds a simple WebMethod that I'm calling via JQuery Ajax. See below:
(Please be aware this is proof-of-concept code, not production code!)
<!DOCTYPE html>
<%# Page Language="C#" %>
<%# Import Namespace="System.Data" %>
<%# Import Namespace="System.Data.SqlClient" %>
<html>
<head runat="server">
<title>Untitled</title>
<script runat="server" type="text/c#">
[System.Web.Services.WebMethod]
public static int GetData(int Id)
{
string connectionString = "Data Source=xxx;Initial Catalog=xxx;User Id=xxx;Password=xxx;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
string query = "SELECT AVG(Number) FROM Data WHERE ID = #Id;";
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("#Id", Id);
connection.Open();
return (int)command.ExecuteScalar();
}
}
}
</script>
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
function getAvg() {
$.ajax({
type: 'POST',
url: "WebMethodAjaxExample.aspx/GetData",
data: JSON.stringify({Id: $('#tbId').val()}),
contentType: 'application/json',
success: function (data, textStatus) {
$('#theParagraph').text(data.d);
}
})
}
</script>
</head>
<body>
<div>
<input type="text" id="tbId" />
<button onclick="getAvg()">Go</button>
</div>
<p id="theParagraph"></p>
</body>
</html>
I've sanity checked the the SQL query and know that it returns a FLOAT (seven-and-a-bit). However, as you can see my WebMethod returns an int. Hence my page was always rounding the number.
I decided to change the WebMethod return type and the ExecuteScalar casting to Double. But still the page was returning "7".
After a bit of tinkering the most interesting fact I learned was that when I decided to change the WebMethod name in the C# code to GetDatum, and made the relevant change to the JQuery Ajax function name too, running the page this time I get a return status 500 from the Ajax call with "Unknown Web Method" as the error message.
It feels like the page is not being dynamically recompiled as I would expect it to be, instead it is still using a cached version even though the request header states "no-cache".
If it's of any help, the page is hosted in Sharepoint 2010.
Can anyone understand what's going on?
UPDATE: Recycling the application pool makes the most up to date WebMethod code work, but further updates are not reflected until the application pool is reset again.
I grabbed this from another answer that I can't seem to find the link for, but you don't need to reset the whole application pool! I have an ASMX file that uses AJAX to pull data from a web service. I was going crazy because updating the web service was not making changes to the data that the web page was pulling.
Add this in your code behind's Page Load and it'll clear the cache and use the newly updated web service:
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(DateTime.Now);
Response.Cache.SetNoServerCaching();
Response.Cache.SetNoStore();
This does exactly what I need it to, but I think I'd really only need the SetExpires line to clear the cache for this page.

MVC3 - Ajax actionlink - OnBegin, onComplete

Using MVC3, C#, and the Razor View Engine:
I have a form that has an Ajax Action link. In the options I'm trying to specify OnBegin and OnComplete javascript function calls. In this question, I took out the meat of the functions and simply added alerts so that I could verify that the functions where being hit. What I really want to do with these functions is to use $.blockUI for the duration of the ajax call.
The pertinent code looks like this:
#Ajax.ActionLink("my test link", "myAction", new { Controller = "myController" }, new AjaxOptions { OnBegin = "ajaxStart", OnComplete = "ajaxStop" })
<script type="text/javascript">
function ajaxStart() {
alert("start");
}
function ajaxStop() {
alert("stop");
}
</script>
For some reason, the two functions never get called as specified. I have tried it with and without the parentheses, sucha as this:
#Ajax.ActionLink("my test link", "myAction", new { Controller = "myController" }, new AjaxOptions { OnBegin = "ajaxStart()", OnComplete = "ajaxStop()" })
Neither work.
Any ideas?
Thanks,
Tony
Make sure you have included the following script to your page:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
and that you have enabled unobtrusive ajax in your web.config:
<appSettings>
...
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
In ASP.NET MVC 3 unobtrusive javascript is used with jQuery so uif you don't include the proper scripts, the HTML5 data-* attributes that are emitted by the html helpers are not interpreted and there is no AJAX request being sent.
You can try to put the <script> bloc before the Ajax.ActionLink method call.
Use this syntax for the ajax link:
#Ajax.ActionLink("my test link", "myAction", "myController", new AjaxOptions { OnBegin = "ajaxStart", OnComplete = "ajaxStop" })
and remember to put the import of jquery.unobtrusive-ajax.min.js in your view or in _Layout.cshtml
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

Categories

Resources