jquery $.ajax call for MVC actionresult which returns JSON triggers .error block - asp.net-mvc-3

I have the following $.ajax post call. It would go through the action being called but then it would trigger the "error" block of the function even before the actionresult finishes. Also, it seems to reload the whole page after every pass.
var pnameVal = '<%: this.ModelCodeValueHelper().ModelCode%>';
var eidVal = '<%: ViewBag.EventId %>';
var dataV = $('input[ name = "__RequestVerificationToken"]').val();
var urlVal = '<%: Url.Action("New") %>';
alert('url > ' + urlVal);
alert('pname - ' + pnameVal + ' eid - ' + eidVal + ' dataV = ' + dataV);
$.ajax({
url: urlVal,
//dataType: "JSONP",
//contentType: "application/json; charset=utf-8",
type: "POST",
async: true,
data: { __RequestVerificationToken: dataV, pname: pnameVal, eId: eidVal },
success: function (data) {
alert('successssesss');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest);
alert(textStatus);
alert(errorThrown);
alert('dammit');
}
})
.done(function (result) {
if (result.Success) {
alert(result.Message);
}
else if (result.Message) {
alert(' alert' + result.Message);
}
alert('done final');
//$('#search-btn').text('SEARCH');
waitOff();
});
This is the action
[HttpPost]
public ActionResult New(string pname, int eid)
{
var response = new ChangeResults { }; // this is a viewmodel class
Mat newMat = new Mat { "some stuff properties" };
Event eve = context.Events.FirstOrDefault(e => e.Id == eid);
List<Mat> mats = new List<Mat>();
try
{
eve.Mats.Add(newMat);
icdb.SaveChanges();
mats = icdb.Mats.Where(m => m.EventId == eid).ToList();
response.Success = true;
response.Message = "YES! Success!";
response.Content = mats; // this is an object type
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
response.Content = ex.Message; // this is an object type
}
return Json(response);
}
Btw, on fiddler the raw data would return the following message:
{"Success":true,"Message":"Added new Mat.","Content":[]}
And then it would reload the whole page again. I want to do an ajax call to just show added mats without having to load the whole thing. But it's not happening atm.
Thoughts?

You probably need to add e.preventDefault() in your handler, at the beginning (I am guessing that this ajax call is made on click, which is handled somewhere, that is the handler I am talking about).

Related

Ajax post method returns undefined in .net mvc

I have this ajax post method in my code that returns undefined. I think its because I have not passed in any data, any help will be appreciated.
I have tried passing the url string using the #Url.Action Helper and passing data in as a parameter in the success parameter in the ajax method.
//jquery ajax post method
function SaveEvent(data) {
$.ajax({
type: "POST",
url: '#Url.Action("Bookings/SaveBooking")',
data: data,
success: function (data) {
if (data.status) {
//Refresh the calender
FetchEventAndRenderCalendar();
$('#myModalSave').modal('hide');
}
},
error: function (error) {
alert('Failed' + error.val );
}
})
}
//controller action
[HttpPost]
public JsonResult SaveBooking(Booking b)
{
var status = false;
using (ApplicationDbContext db = new ApplicationDbContext())
{
if (b.ID > 0)
{
//update the event
var v = db.Bookings.Where(a => a.ID == a.ID);
if (v != null)
{
v.SingleOrDefault().Subject = b.Subject;
v.SingleOrDefault().StartDate = b.StartDate;
v.SingleOrDefault().EndDate = b.EndDate;
v.SingleOrDefault().Description = b.Description;
v.SingleOrDefault().IsFullDay = b.IsFullDay;
v.SingleOrDefault().ThemeColor = b.ThemeColor;
}
else
{
db.Bookings.Add(b);
}
db.SaveChanges();
status = true;
}
}
return new JsonResult { Data = new { status } };
}
Before the ajax call, you should collect the data in object like,
var requestData= {
ModelField1: 'pass the value here',
ModelField2: 'pass the value here')
};
Please note, I have only added two fields but as per your class declaration, you can include all your fields.
it should be like :
function SaveEvent(data) {
$.ajax({
type: "POST",
url: '#Url.Action(Bookings,SaveBooking)',
data: JSON.stringify(requestData),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.status) {
//Refresh the calender
FetchEventAndRenderCalendar();
$('#myModalSave').modal('hide');
}
},
error: function (error) {
alert('Failed' + error.val );
}
})
}
Try adding contentType:'Application/json', to your ajax and simply have:
return Json(status);
In your controller instead of JsonResult. As well as this, You will need to pass the data in the ajax code as a stringified Json such as:
data:JSON.stringify(data),
Also, is there nay reason in particular why it's a JsonResult method?

ASP.net cascading dropdown list

trying to implement country state dropdown in mvc but couldn't..
conotroller :-
[HttpGet]
public ActionResult GetCities(int StateId)
{
Business.Services.City cityService = new Business.Services.City();
List<Business.Models.City> stateList = cityService.GetCityByStateId(StateId);
//var jsonSerialiser = new JavaScriptSerializer();
//var json = jsonSerialiser.Serialize(stateList);
return Json(new { stateList }, JsonRequestBehavior.AllowGet);
}
method:
public List<Models.City> GetCityByStateId(int StateId)
{
try
{
var list = new List<SelectListItem>();
Collection<DBParameters> parameters = new Collection<DBParameters>();
parameters.Add(new DBParameters() { Name = "StateId", DBType = DbType.Int32, Value = StateId });
var city = this.ExecuteProcedure<Models.City>("GetCityByState", parameters).ToList();
//if (city != null && city.Count > 0)
//{
// list = city.Select(x => new SelectListItem { Text = x.CityName, Value = x.StateId.ToString() }).ToList();
//}
return city;
}
catch (Exception ex)
{
throw;
}
}
change event:
$('.ddlstate').change(function () {
debugger;
$.ajax({
url: '#Url.Action("GetCities", "User")',
type: "GET",
data: { StateId: $(this).val() },
dataType: "json",
success: function (result) {
debugger;
//alert(result.stateList[0].CityId);
$.each(result.stateList, function () {
debugger;
$('.cityddl').append($("<option></option>").val(CityId).html(CityName));
});
},
error: function (result, status, jQxhr) {
alert("Error: " + result + "-" + status + "-" + jQxhr);
}
});
});
i get count of the citites in method and controller but when i run project and change state dropdown i got blank city dropdown. what is wrong?
It looks like you're missing a couple of things in the $.each() call.
You should pass the JSON result from the ajax call to the $.each
You also need to provide a parameter to the callback function so that the callback function has something to work with
It could look something like this:
$.each(result.stateList, function(index, city) {
$('.cityddl').append($("<option></option>").val(city.CityId).html(city.CityName));
});

jQuery Form plugin doesn't calls Method in IE 8

I am trying to upload files to server, but when i am submitting form it doesn't calls ActionResult. It works in chrome, FF but not in IE. When i am removing enctype="multipart/form-data" attribute from form in IE, then it calls method, but without file uploading...
I have such input:
<input id="jqueryfileupload" type="file" name="files" data-upload-id="#documentUniqueId"
data-url="#Url.Action(MVC.Profile.Documents().AddRouteValue("documentUniqueId", documentUniqueId))" multiple>
jQuery code:
$(document).on('change', '.documents-upload-container #jqueryfileupload', function (e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
//input itself is not in the form tag, so i am creating form here and
//submitting it this way
var formContainer = $('<form action="' + $this.data('url') + '" enctype="multipart/form-data" method="POST"></form>');
$this.appendTo(formContainer);
var contentTypeOption = $.browser.msie ? 'text/html' : 'application/json';
var iframeOption = $.browser.msie ? true : false;
var options = {
dataType: 'json',
//contentType: contentTypeOption,
//iframe: iframeOption,
method: 'POST',
success: function (response, textStatus, xhr, form) {
alert(response);
},
error: function (xhr, textStatus, errorThrown) {
alert(xhr);
alert(textStatus);
alert(errorThrown);
},
clearForm: true
};
$(formContainer).ajaxSubmit(options);
return false;
});
There are no errors and alerts are not throwing at all in IE. Just method is not called...
Action Method:
[HttpPost]
public virtual ActionResult Documents(IEnumerable<HttpPostedFileBase> files, string documentUniqueId)
{
var result = new ContentResult();
if (files != null)
{
foreach (var item in files)
{
string docName = documentUniqueId + "_" + item.FileName;
var filename = Path.Combine(Server.MapPath("~/App_Data"), docName);
item.SaveAs(filename);
}
var docs = files.Select(x => new
{
url = Url.Action(MVC.Profile.Documents(documentUniqueId + "_" + x.FileName, x.ContentType)),
name = x.FileName,
contentType = x.ContentType,
id = documentUniqueId + "_" + x.FileName
});
result.Content = new JavaScriptSerializer().Serialize(docs);
return result;
}
result.Content = new JavaScriptSerializer().Serialize(new { success = false });
return result;
}
[HttpGet]
public virtual ActionResult Documents(string fileName, string contentType)
{
var docPath = Path.Combine(Server.MapPath("~/App_Data"), fileName);
return File(docPath, contentType);
}
I use this plugin : http://malsup.com/jquery/form/
I think you are not inserting the form in the page. that's the problem. you have to add formContainer.appendTo(container);
try this code:
$(document).on('change', '.documents-upload-container #jqueryfileupload', function (e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
var container = $this.parents('.documents-upload-container').addClass("current-container");
var formContainer = $('<form action="' + $this.data('url') + '" enctype="multipart/form-data" method="post"></form>');
$this.appendTo(formContainer);
formContainer.appendTo(container);
var contentTypeOption = $.browser.msie ? 'text/plain' : 'application/json';
var iframeOption = $.browser.msie ? true : false;
var options = {
dataType: 'json',
contentType: contentTypeOption,
//iframe: iframeOption,
method: 'POST',
//data: { 'isIE': iframeOption },
success: function (response, textStatus, xhr, form) {
alert(response);
},
error: function (xhr, textStatus, errorThrown) {
alert(xhr);
alert(textStatus);
alert(errorThrown);
},
clearForm: true
};
formContainer.ajaxSubmit(options);
return false;
});

Passing jquery object to MVC action

I am trying to use .ajax() to post a People object to a MVC2 action that expects a ViewModel as parameter. The ViewModel has a People property.
The problem is that when the MVC action is activated, the ajax() postback People object is always null. I used Fiddler to diagnose the problem. The property values in the People object are all contained in the header. Here is my client jQuery script. Please note that I used three methods to stuff the property values into People object, but none of them works.
StaffDlg.delegate("#SaveButton", "click",
function (e) {
e.preventDefault();
People["PKey"] = $("#PKey").val();
People["FName"] = $("#FName").val();
People["LName"] = $("#LName").val();
People["MName"] = $("#MName").val();
People["SSN"] = $("#SSN").val();
People["Gender"] = $("#Gender").val();
People["DOB"] = $("#DOB").val();
People["BirthPlace"] = $("#BirthPlace").val();
People["NetworkAccount"] = $("#NetworkAccount").val();
var pkey = $("#PKey").val();
var action;
if (!isNaN(parseFloat(pkey)) && isFinite(pkey)) {
action = "Edit" + "/" + pkey;
}
else {
action = "Create";
}
$.ajax({
url: getRootUrl() + "/Staff/" + action,
//data: { FName: $("#FName").val(), LName: $("#LName").val(), MName: $("#MName").val(),
// SSN: $("#SSN").val(), Gender: $("#Gender").val(), DOB: $("#DOB").val(),
// BirthPlace: $("#BirthPlace").val(), NetworkAccount: $("#NetworkAccount").val()
//},
//data: JSON.stringify(People),
data: $("Form").serialize(),
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST",
success: function (result) {
$("#ajaxResponse").addClass("whiteOnGreen").html("Update succeeded");
},
error: function (qXHR, textStatus, errorThrown) {
$("#ajaxResponse").addClass("whiteOnRed").html("Failed to save the record!\r\n" +
textStatus + ": " + errorThrown + "\r\n" +
"data : " + JSON.stringify(People));
}
})
}
);
and here is the MVC action.
public ActionResult Edit(int id, StaffViewModel updatedStaff)
{
People staff = _staffService.GetStaff(id);
if (updatedStaff == null)
return View("NotFound");
if (ModelState.IsValid)
{
TryUpdateModel<People>(staff, "staff");
staff.RecordLastUpdated = DateTime.Now;
staff.UpdatedBy = HttpContext.User.Identity.Name;
_staffService.SaveStaff();
//return RedirectToAction("Index", new { id = thisStaff.PKey });
if (Request.IsAjaxRequest())
return this.Json(staff, JsonRequestBehavior.AllowGet);
else
{
if (string.IsNullOrEmpty(updatedStaff.previousURL))
return Redirect("/Staff/Startwith/" + staff.LName.Substring(1, 1));
else
return Redirect(updatedStaff.previousURL);
}
}
else
{
if (Request.IsAjaxRequest())
{
string errorMessage = "<div class='whiteOnRed error'>"
+ "The following errors occurred:<ul>";
foreach (var key in ModelState.Keys)
{
var error = ModelState[key].Errors.FirstOrDefault();
if (error != null)
{
errorMessage += "<li>"
+ error.ErrorMessage + "</li>";
}
}
errorMessage += "</ul></div>";
return Json(new { Message = errorMessage });
}
else
return View(updatedStaff);
}
}
You state that the form expects a StaffViewModel as a parameter, and a StaffViewModel has a People property... but you are not passing the full StafFViewModel object - instead you are passing a People object from the Ajax call, and hoping that the People property gets populated on the MVC end.
There is a disconnect there and the auto-binder doesn't know how to bridge it.
Try creating a controller method with a (int, People) signature, and see if that works for you.
Otherwise, you might need to create a custom binder.
Try removing dataType and contentType settings from your ajax call:
$.ajax({
url: getRootUrl() + "/Staff/" + action,
data: $("Form").serializeArray(),
type: "POST",
success: function (result) {
$("#ajaxResponse").addClass("whiteOnGreen").html("Update succeeded");
},
error: function (qXHR, textStatus, errorThrown) {
$("#ajaxResponse").addClass("whiteOnRed").html("Failed to save the record!\r\n" +
textStatus + ": " + errorThrown + "\r\n" +
"data : " + JSON.stringify(People));
}
})
I solved the problem with the .ajax() not posting the form values to the MVC Create(People person) action. It was the parameter type that this different than the one used in Edit(StaffViewModel). Now both action accept the same type of parameter, StaffViewMode.

Jquery and live act wired but act ok after force refresh in IE

somthing is wrong with my code and i can't get what it is...
i have a div id = "personaltab"
i have a form in side it to login the user with username and password. if success the jquery empty the div and puts in the form of the bidding.
if the user try to bid the other ajax that assign to the button is working but for some reason skips the empty and just adding the responded ajax to the div
i have checked that in IE and chrome and it is working fine in chrome
here are my codes
$("#login").click(function() {
var id = $("input#pid").val();
var user = $("input#puser").val();
var pass = $("input#ppass").val();
var dataString = 'id='+ id + '&user='+ user + '&pass=' + pass;
if (user == "") {
alert("error");
$("input#puser").focus();
return false;
}
if (pass == "") {
alert("error");
$("input#ppass").focus();
return false;
}
$.ajax({
type: "POST",
url: "loginpersonal.asp",
data: dataString,
success: function(msg)
{
if (msg=="False") {
alert("error");
$("#personaltab").show();
}
else {
$("#personaltab").fadeOut("normal",function(){
$("#personaltab").empty();
$("#personaltab").append(msg);
$("#personaltab").slideDown();
});
}
},
error: function (XMLHttpRequest, textStatus, errorThrown)
{
alert('error');
}
});
return false;
});
$("#sendbid").live("click", function(){
var startat = $("input[name=startat]").val();
var sprice = $("input[name=sprice]").val();
if (parseInt(sprice)<=parseInt(startat)) {
alert("error");
$("input[name=sprice]").focus();
return false;
}
else {
var payment = $("select[name=payment]").val();
if ($('input[name=credit]').is(':checked') ){
var credit = true;
}
var prodid = $("input[name=id]").val();
var dataString = 'id='+ prodid + '&price='+ sprice + '&payment=' + payment + '&credit=' + credit;
$.ajax({
type: "POST",
url: "loginpersonal.asp",
data: dataString,
success: function(msg)
{
$("#personaltab").empty();
$("#personaltab").append(msg);
$("#personaltab").show();
},
error: function (XMLHttpRequest, textStatus, errorThrown)
{
alert('error');
}
});
}
return false;
});
Solved:
i had inside a and for some reason the div that need to get the ajax by his id was duplicated
don't ask :-)

Resources