I am trying to call a controller action in ASP.Net MVC 5 from a jQuery ajax method. Everything seems to be in place and correct, however my ajax keeps failing. The error return keeps presenting itself and my page does not refresh. However, my controller does get hit. If I set a break point in the C# code under the specific action I am trying to access all goes according to plan.
Yet still the ajax returns an error and the page is never redirected to.
Here is my jQuery script
$(document).ready(function () {
$('.searchbox').on('search', function () {
if ($(this).val() == undefined || $(this).val() == '') {
$.ajax({
type: 'GET',
contentType: 'application/json',
dataType: 'json',
url: '#Url.Action("Index","Company")',
error: function () { alert('error'); }
});
}
});
});
Any suggestions? I can post more code if need be. I am using a search input type and this fires when I clear the search box.
Thanks for any help I get!
Here is the controller
[HttpGet]
public ActionResult Index(Int32? resultsPerPage, Int32? startingIndex, Int32? currentPage, String searchExpression)
{
List<ProspectModel> prospects = ProspectManager.LoadProspects(searchExpression);
resultsPerPage = resultsPerPage ?? 25;
startingIndex = startingIndex ?? 0;
currentPage = currentPage ?? 1;
if(!String.IsNullOrWhiteSpace(searchExpression))
{
ViewBag.Pages = 0;
ViewBag.TotalRecords = prospects.Count;
ViewBag.CurrentIndex = 0;
ViewBag.ResultsPerPage = resultsPerPage;
ViewBag.CurrentPage = 1;
ViewBag.LastPageStartingIndex = 1;
ViewBag.SearchExpression = searchExpression;
return View(prospects);
}
List<ProspectModel> model = prospects.GetRange((Int32)startingIndex, (Int32)resultsPerPage);
ViewBag.TotalRecords = prospects.Count;
ViewBag.Pages = (prospects.Count / resultsPerPage) + ((prospects.Count / resultsPerPage) % 2 != 0 ? 1 : 0);
ViewBag.CurrentIndex = startingIndex + resultsPerPage;
ViewBag.ResultsPerPage = resultsPerPage;
ViewBag.CurrentPage = currentPage;
ViewBag.LastPageStartingIndex = ((prospects.Count / resultsPerPage) % 2 == 0 ? prospects.Count - resultsPerPage : prospects.Count - ((prospects.Count / resultsPerPage) % 25));
ViewBag.SearchExpression = null;
return View(model);
}
In MVC GET ajax requests are blocked by default , you have to change it to Post , or allow GET
return Json("string or model here" ,JsonRequestBehavior.AllowGet);
try changing your jQuery to type 'POST' , just once and see if that fixes it. If it does then you can try the code I provided.
You are getting a 404 because your Action Index does not have a path that accepts 0 parameters , you have all your int's set to nullable , but you have to atleast provide that parameter searchExpression.
Try hardcoding the url instead of Razor, and try passing it sometype of string.
$.ajax({
type: 'GET',
contentType: 'application/json',
data: { searchExpression : "test" },
dataType: 'json',
url: '/Company/Index',
success: function(data) { alert('success'); },
error: function () { alert('error'); }
});
the other answer is probably also a lot of help , I was going to reccommend also removing the contentType and dataType, they are not needed , and jQuery does a very good job at making an educated guess as to what the types are supposed to be
$.ajax({
type: 'GET',
data: { searchExpression : "test" },
url: '/Company/Index',
success: function(data) { alert('success'); },
error: function () { alert('error'); }
});
If I read your initial post correctly, then you're saying that you get all the way to and past the return View() call in your controller, but your jQuery AJAX call says there was an error.
Your View is probably HTML, is that right to say? If so, because in your AJAX call you've specified that you're expecting JSON, jQuery is trying to parse the response as JSON before giving it to you. This could be the root cause of your error.
In the controller, replace the return View with:
return JSON(new { Test = "Hello!" }, JsonRequestBehavior.AllowGet);
And in a success handler to your AJAX call:
success: function(data) { alert(data.Test); }
If that works, then you need to either specify in your AJAX that you're going to be receiving HTML, or return your model in JSON from MVC and handle it in the success function, depending on what you are trying to achieve.
If you want to return HTML to your ajax call, then try this sample I just toyed with:
Controller
public class HomeController : Controller
{
public ActionResult Search(
Int32? resultsPerPage,
Int32? startingIndex,
Int32? currentPage,
String searchExpression)
{
return View();
}
}
JavaScript
$.ajax({
type: 'GET',
contentType: 'application/json',
dataType: 'html',
url: '#Url.Action("Search", "Home")',
success : function(data){ alert(data);},
error: function () { alert('error'); }
});
The key is the dataType. You need to set that to the type of content you expect to be returned from the ajax call, in your case you want to return HTML. Not setting that correctly will result in the error function being called.
Related
I have an Ajax Call and a Controller with some methods and there is something weird.
The Ajax call can reach the Controller Method. The method is returning the value perfectly, no errors, nothing. However, in the AJAX the return is coming with error (not on success of Ajax).
Moreover, If I inspect the return I can see the correct values on responseJson, but the status is 404 and statusText is "error" ({"readyState":4,"status":404,"statusText":"error"})
Anyone have an idea what is going on? There is no error in backend, however error in Ajax.
Controller Method
public JsonResult SceneListUpdated(string sceneId)
{
SceneListModel model = new SceneListModel();
var licenseValidationState = KeygenLicenseState.CheckLicense();
if (licenseValidationState == 0)
{
SceneListService sceneService = new SceneListService();
model = sceneService.GetSceneListUpdated(sceneId);
return Json(new { Success = true, data = model }, JsonRequestBehavior.AllowGet );
}
return Json(new { Success = false, data = "" }, JsonRequestBehavior.AllowGet);
}
Ajax Function
$.ajax({
url: "/api/test/SceneList/SceneListUpdated?sceneId=" + sceneIdAux, //Method in controller
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
success: function (e) {
},
error: function (data) {
}
});
try to fix the ajax
$.ajax({
url: "/api/test/SceneList/SceneListUpdated/"+ sceneIdAux, //Method in controller
type: "GET",
success: function (e) {
},
error: function (data) {
}
});
and maybe you can try one of these routing since you have 404
[Route("{sceneId}")]
[Route("~/api/SceneList/SceneListUpdated/{sceneId}")]
public JsonResult SceneListUpdated(string sceneId)
I am calling jquery function on dropdown value change jquery method is ,
function MyFunction() {
alert($('#DDlSurvey').val());
$.ajax({
url: "#Url.Action("GetSelectedQuestion", "ConductSurveyController")",
data: { prefix: $('#DDlSurvey').val() },
type: "GET",
dataType: "json",
success: function (data) {
// loadData(data);
alert(data)
alert("Success");
},
error: function () {
alert("Failed! Please try again.");
}
});
//$('#YourLabelId').val('ReplaceWithThisValue');
}
</script>
Function I'm calling and I am getting dropdown value alert
Now, Function that I am calling is "GetSelectedQuestion" in controller "ConductSurveyController"
Method is like ,
[HttpPost]
public JsonResult GetSelectedQuestion(int prefix)
{
List<SelectList> Questions=new List<SelectList>();
// Here "MyDatabaseEntities " is dbContext, which is created at time of model creation.
SurveyAppEntities ObjectSur = new SurveyAppEntities();
// Questions = ObjectSur.Surveys.Where(a => a.ID.Equals(prefix)).toToList();
I don't think this method is calling as I am getting error
"Failed! Please try again"
From my script.
Hopes for your suggestions
Thanks
var e = from q in ObjectSur.Questions
join b in ObjectSur.SurveyQuestions on q.ID equals b.QuestionID where b.SurveyID.Equals(prefix)
select q ;
return new JsonResult { Data = e, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
I think you are using controller name straight forward. your ajax code be something like this.
var PostData= { prefix: $('#DDlSurvey').val() }
var ajaxOptions = {
type: "GET",
url: '#Url.Action("GetSelectedQuestion", "ConductSurvey")',//Actionname, ControllerName
data: PostData,
dataType: "json",
success: function (result) {
console.log(result);
},
error: function (result) {
}
};
$.ajax(ajaxOptions);
Your method in your controller is decorated with HttpPost, while in your ajax you have specified the type of your request is get . You can either change your method to get like this:
[HttpGet]
public JsonResult GetSelectedQuestion(int prefix)
{
}
Or change your request type to post in your Ajax call:
$.ajax({
url: "#Url.Action("GetSelectedQuestion", "ConductSurveyController")",
data: { prefix: $('#DDlSurvey').val() },
type: "Post",
Also the Controller is redundant in ConductSurveyController, you need to remove it and simply call it as ConductSurvey:
url: '#Url.Action("GetSelectedQuestion", "ConductSurvey")',
I am realy struggling with this and would apprecate any advice.
I have this field
<input id="scanInput" type="text" placeholder="SCAN" class="form-control" />
For which I would like to make an ajax call when the field changes, so I tried
<script>
$("#scanInput").change(function () {
console.log('ye');
$.getJSON("?handler=GetPartDetails", function (data) {
//Do something with the data.
console.log('yay?');
}).fail(function (jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log("Request Failed: " + err);
});
});
</script>
Where my PageModel has this method
[HttpPost]
public IActionResult GetPartDetails()
{
return new JsonResult("hello");
}
and the url for the page in question is /packing/package/{id}
Now when I change the input value, I see ye on the console, and I can see that the network called http://localhost:7601/Packing/Package/40?handler=GetPartDetails (the correct URL I think?) with status code 200
But My breakpoint in GetPartDetails never hits, and I don't see yay? in the console.
I also see this message from the fail handler:
Request Failed: parsererror, SyntaxError: JSON.parse: unexpected character at line 3 column 1 of the JSON data
But I'm not even passing any JSON data... why must it do this
I also tried this way :
$.ajax({
type: "POST",
url: "?handler=GetPartDetails",
contentType : "application/json",
dataType: "json"
})
but I get
XML Parsing Error: no element found
Location: http://localhost:7601/Packing/Package/40?handler=GetPartDetails
Line Number 1, Column 1:
I also tried
$.ajax({
url: '/?handler=Filter',
data: {
data: "input"
},
error: function (ts) { alert(ts.responseText) }
})
.done(function (result) {
console.log('done')
}).fail(function (data) {
console.log('fail')
});
with Action
public JsonResult OnGetFilter(string data)
{
return new JsonResult("result");
}
but here I see the result text in the console but my breakpoint never hits the action and there are no network errors..............
What am I doing wrong?
Excuse me for posting this answer, I'd rather do this in the comment section, but I don't have the privilege yet.
Shouldn't your PageModel look like this ?
[HttpPost]
public IActionResult GetPartDetails() {
return new JsonResult {
Text = "text", Value = "value"
};
}
Somehow I found a setup that works but I have no idea why..
PageModel
[HttpGet]
public IActionResult OnGetPart(string input)
{
var bellNumber = input.Split('_')[1];
var partDetail = _context.Parts.FirstOrDefault(p => p.BellNumber == bellNumber);
return new JsonResult(partDetail);
}
Razor Page
$.ajax({
type: 'GET',
url: "/Packing/Package/" + #Model.Package.Id,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {
input: barcode,
handler: 'Part'
},
success: function (datas) {
console.log('success');
$('#partDescription').html(datas.description);
}
});
For this issue, it is related with the Razor page handler. For default handler routing.
Handler methods for HTTP verbs ("unnamed" handler methods) follow a
convention: On[Async] (appending Async is optional but
recommended for async methods).
For your original post, to make it work with steps below:
Change GetPartDetails to OnGetPartDetails which handler is PartDetails and http verb is Get.
Remove [HttpPost] which already define the Get verb by OnGet.
Client Request
#section Scripts{
<script type="text/javascript">
$(document).ready(function(){
$("#scanInput").change(function () {
console.log('ye');
$.getJSON("?handler=PartDetails", function (data) {
//Do something with the data.
console.log('yay?');
}).fail(function (jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log("Request Failed: " + err);
});
});
});
</script>
}
You also could custom above rule by follow the above link to replace the default page app model provider
My setup: asp.net mvc web app
I am having trouble getting a value from a controller back to the $.Ajax call (see below). The controller deletes a record in a database and counts some other records.
$.ajax({
type: "POST",
url: actions.action.RemoveItem + "?id=" + dataId,
contentType: "application/json; charset=utf-8",
dataType: "json",
traditional: true,
success: function (result) {
alert(result);
},
error: function (result) {
alert("Error");
}});
[HttpPost]
public JsonResult RemoveItem(int id)
{
... delete a record in the db
itemsCount = .... counts of some other records in the db
if (deletedRecord.id != null)
{
return Json(new { itemsCount });
}
else
{
return JsonError();
}
}
The ajax call and the controller work properly, however when I try to use the returned value in the success function, the alert(result) gives [object object].
I have looked through all related posts, but could not find a solution that worked. Could someone give me a hint where the problem could be and how to make it work?
Thank you in advance and regards, Manu
Result is a javascript object so alert works properly. If you want to alert it's structure as JSON use JSON.stringify() method like this:
alert(JSON.stringify(result));
If you want to access your itemsCount, just use dot or bracket notation:
alert(result.itemsCount);
alert(result['itemsCount']);
I have the strangest situation. I have two ajax POST. First I had problems passing the parameters to the controller but at some point I got them trough and with some debugging I figured out that I only get all of the values to the controller if my ajax definition is followed by an alert.
One of them:
$.ajax({
type: 'POST',
url: '/Contact/IntresseAnmälan/',
dataType: 'json',
data: {
Namn: $('#namn').val(),
Mail: $('#mail').val(),
Info: $('#meddelande').val(),
Telefon: $('#nr').val(),
IsEnkel: false,
PassId: function () {
var url = window.location.pathname;
var id = url.substring(url.lastIndexOf('/') + 1);
return id;
},
Participanter: getParticipant(),
ParticipantMail: getParticipantMail()
},
traditional: true,
success: function (result) {
// window.location.href = '#Url.Action("IntresseAnmälan", "Contact")';
}
});
alert("Hur sparas dina uppgifter?");
Here are my Getters for name and mail. The form-elements(input type mail and text) theese are dynamicly added to the form if the user wants clicks a button two inputs are added. Then theese functions returns an array with the inputed values from the form.
function getParticipant() {
var p = [];
for (var i = 1; i <= participantCount; i++) {
var name = '#anNamn' + i;
p[i -1] = $(name).val()
}
return p;
}
function getParticipantMail() {
var p = [];
for (var i = 1; i <= participantCount; i++) {
p[i -1] = $('#anMail' + i).val();
}
return p;
}
And here is my controller. I've removed the body in the controller. It saves to the Db and send a verification mail to the admin.
[HttpPost]
public ActionResult IntresseAnmälan(BokningContainer bokning)
{
//Saves to Db and Send a verification mail to admin
}
If I exclude the alert after the ajax some parameters are passed, I think it's Namn and Mail, but most of them not passed. I'm quite puzzled.
Also, is ajax the only way to pass an object to a controller from jQuery?
Also, is ajax the only way to pass an object to a controller from
jQuery?
No, you can use a regular HTML Form to submit your data, you just have to conform to the expected object in the controller Action (should be decorated with HttpPostAttribute) - There is a Model-Binding process which attempting to bind the Request data to your domain object.
You don't need to pass every field's value using jQuery. Instead you can create a form whose data you want to post like :
<form id="frmTest">
... add input types here
</form>
and you can pass data of form using $('#frmTest').serialize() method to the controller
$.ajax({
type: "POST",
data: $('#frmTest').serialize(),
url: "url",
dataType: "json",
success: function (data) { alert('worked!'); },
error: function (data) {
alert('error');
}
});