Ajax Error 500: A circular reference was detected - ajax

I'm trying to update my view with new information, so when it is sent to the controller for saving, the information gets passed.
The same method works fine when creating an object (Create-View) but throws an ajax error 500: A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.Gutscheine_', when editing an existing object (Edit-View).
Here's my ajax-call:
function onCloseButtonClick(s) {
$.ajax({
type: "POST",
url: "#Url.Action("UpdateGutscheinEdit")",
data: { sBild: document.getElementById(s).value, bIcon: true },
success: function (response) {
document.getElementById("sBild").value = response.sBild;
document.getElementById("bIcon").value = response.bIcon;
document.getElementById("fileToUpload").value = "";
popupIconAuswaehlen.Hide();
},
error: function (jqxhr, status, exception) {
alert(jqxhr.status); //throws 500
alert('Exception', exception);
}
})
}
And here's the method:
public ActionResult UpdateGutscheinEdit(string sBild, bool bIcon)
{
Gutscheine currentGutschein = Session["CurrentGutscheinEdit"] as Gutscheine;
if (!string.IsNullOrEmpty(sBild))
{
currentGutschein.sBild = sBild;
currentGutschein.bIcon = bIcon;
}
Session["CurrentGutscheinEdit"] = currentGutschein;
return Json(currentGutschein);
}
The Edit-(get)-method is a standard one:
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Gutscheine gutscheine = db.Gutscheine.Find(id);
if (gutscheine == null)
{
return HttpNotFound();
}
if(Session["CurrentGutscheinEdit"] == null)
{
Session["CurrentGutscheinEdit"] = gutscheine;
}
return View(Session["CurrentGutscheinEdit"] as Gutscheine);
}
Circular reference gives some hint, but I'm pretty new to all this, so it doesn't help me much in figuring out the problem.
If you have any ideas how to fix this, please let me know. Any help is appreciated!

Adding db.Configuration.ProxyCreationEnabled = false; before getting the object from the database did the trick.
Finished code: (I also removed some stuff at the end which screwed something else up)
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
db.Configuration.ProxyCreationEnabled = false;
Gutscheine gutscheine = db.Gutscheine.Find(id);
if (gutscheine == null)
{
return HttpNotFound();
}
Session["CurrentGutscheinEdit"] = gutscheine;
return View(Session["CurrentGutscheinEdit"] as Gutscheine);
}
Big thanks to the commenter that provided the link!

Related

Post ajax values to MVC Action Result

Ok, so I have the following Ajax get request going to a [HttpPost] controller method in an ASP.NET MVC 5 application.
The javascript function shown here successfully posts the values to the server side:
<script>
function get_row() {
var one = document.getElementById("data_table").rows[1].cells[0].innerHTML;
var two = document.getElementById("data_table").rows[1].cells[1].innerHTML;
var result = one + "," + two;
//var result = {};
//result.one = document.getElementById("data_table").rows[1].cells[0].innerHTML;
//result.two = document.getElementById("data_table").rows[1].cells[1].innerHTML;
if (result != null) {
$.ajax({
type: 'get',
url: "/Manage/CreateGroupRoleRestriction",
//url: '#Url.RouteUrl(new{ action= "CreateGroupRoleRestriction", controller= "Manage", one = "one", two = "two"})',,
data: { one, two },
//params: { one, two }
/*dataType: String,*/
//success: alert(result)
});
}
else {
alert("Error");
}
}
</script>
However, the issue is that the string values will not post to the Action Result, see below.
The values "one" and "two" are null.
[Authorize(Roles = "Admin")]
[HttpPost]
[Route("/Manage/CreateGroupRoleRestriction?{one,two}")]
[ValidateAntiForgeryToken]
public ActionResult CreateGroupRoleRestriction(FormCollection formCollection, string message2, string one, string two)
{
UserDataBusinessLayer userDataBusinessLayer = new UserDataBusinessLayer();
userDataBusinessLayer.Restrict1(message2);
UserDataBusinessLayer userDataBusinessLayer2 = new UserDataBusinessLayer();
userDataBusinessLayer2.Restrict2();
try
{
UserData userData = new UserData();
TryUpdateModel(userData);
if (ModelState.IsValid)
{
userData.RoleName = formCollection["RoleName"];
UserDataBusinessLayer userDataBusinessLayer3 = new UserDataBusinessLayer();
userDataBusinessLayer3.CreateGroupRestriction(userData, message2, one.ToString(), two.ToString());
return RedirectToAction("CreateGroupRoleRestriction");
}
else
{
userData.RoleName = formCollection["RoleName"];
UserDataBusinessLayer userDataBusinessLayer4 = new UserDataBusinessLayer();
userDataBusinessLayer4.CreateGroupRestriction(userData, message2, one.ToString(), two.ToString());
return RedirectToAction("CreateGroupRoleRestriction");
}
}
catch (Exception ex)
{
Logger.Log(ex);
return RedirectToAction("CreateGroupRoleRestriction");
}
}
Please try changing 'type' in ajax to 'post'.
type: 'post'

My Ajax call is passing a null stringified object to my JSonResult Action, Why?

My Ajax method is calling action method in controller, and succeeding in the call return. However the object I am passing is always null.
I have read many, maybe not all as there are quite a few, similar questions. I have tried different things, such as different variations of removing dataType and contentType from the ajax function. I have set break points in the action and set alerts in scripts to verify the object is not null before sending to the JsonResult Action. I have verified that data from the Action method is reaching the succeeded section of the ajax function.
So Here is the scenario: I have an MVC Core 2.2 index page. I added a search textbox. everything works correctly If I block JS in the browser, So I know the HTML is correct. But I wanted to give an Ajax option for a "more pleasant" user experience. I actually did get the ajax to work on simple hard coded strings. But now for some reason the passed in object is null.
Lets start with the view's script:
//This is the Object I want passed through Ajax
//class pageValues {
// constructor(){
// this.sortColumn = $("#inpSortColumn").val();
// this.sortOrder = $("#inpSortOrder").val();
// this.filter = $("#Filter").val();
// this.message = "";
// this.currentPage = $("#inpCurrentPage").val();
// this.recordsPerPage = $("#inpPageSize").val();
// this.recordCount = 0;
// }
//}
// I also tried as a simple variable without a constructor and added
// default values incase undefined values were causing issues
var pageValues = {
sortColumn: ($("#inpSortColumn").val() == undefined ) ? "LastName" : $("#inpSortColumn").val(),
sortOrder: ($("#inpSortOrder").val() == undefined ) ? "ASC" : $("#inpSortOrder").val(),
filter: ($("#Filter").val() == undefined ) ? "" : $("#Filter").val(),
message: ($("#inpMessage").val() == undefined ) ? "" : $("#inpMessage").val(),
currentPage: ($("#inpCurrentPage").val() == undefined) ? 1: $("#inpCurrentPage").val(),
recordsPerPage: ($("#inpPageSize").val() == undefined) ? 5 : $("#inpPageSize").val(),
totalRecords: ($("#inpTotalRecords").val() == undefined ) ? 0 : $("#inpTotalRecords").val()
};
$(document).ready(function () {
// If we are here, the browser allows JS
// So, replace the submit buttons with Ajax functions
ReplaceHtml();
});
function ReplaceHtml() {
// Search Button
var divSearch = $("#divSearchBtn");
divSearch.hide();
divSearch.empty();
divSearch.append('<button id="btnAjaxSearch" type="button" ' +
'class="" onclick="RequestRecords();">Search</button>');
divSearch.show();
}
// Here we call the Ajax function passing the data object and the callback function
function RequestRecords() {
alert($("#Filter").val()); // This is just to Verify value is present
AjaxCallForRecords(pageValues, ReturnedData);
}
// This is the callback function
function ReturnedData(data) {
// This verifies we hit the callback
alert("inside ajax callback");
// The Verification that the Object returned is valid.
// The problem appeared here,
// The firstname was always the same no matter the Search Filter.
// Telling me the object on the server side receiving the 'pageValues'
// had been recreated due to being null.
alert(data.users[0].firstName);
}
// Of course, here is the ajax function
// I have played around with data and content settings
// When I changed those I got 'Response Errors' but could never get the ResponseText
function AjaxCallForRecords(dataToSend, callback) {
console.log(dataToSend); // This prove Data is here
$.ajax({
type: "GET",
url: '#Url.Action("Index_Ajax","ApplicationUsers")',
data: JSON.stringify(dataToSend),
dataType: "json",
contentType: "application/json",
success: function (data) { callback(data); },
error: function (data) { alert("Error. ResponseText: " + data.responseText); }
});
}
</script>
Ok, Now to the Controller:
public JsonResult Index_Ajax([FromBody] UsersCodeAndClasses.PageValues pageValues)
{
// A break point here reveals 'pageValues' is always null - this is the problem.....
// In the GetFilteredData function I do create a new 'pageValues' object if null
// So my Search 'Filter' will always be empty, and I will always get all the records.
// Get Records
List<InputUser> users = _usersCode.GetFilteredData(pageValues);
// The next block of code assembles the data to return to the view
// Again the 'pageValues' is null because that is what gets passed in, or rather, never assigned
//Build Return Data
UsersCodeAndClasses.AjaxReturnData data = new UsersCodeAndClasses.AjaxReturnData()
{
pageValues = pageValues,
users = users
};
return Json(data);
}
And Finally, The Server side 'pageValues' declaration:
public class PageValues
{
// Class used to pass page and sorting information to Ajax Call
public string sortColumn { get; set; } = "LastName";
public string sortOrder { get; set; } = "ASC";
public string filter { get; set; } = "";
public string message { get; set; } = "";
public int currentPage { get; set; } = 1;
public int recordsPerPage { get; set; } = 5;
public int recordCount { get; set; }
}
public class AjaxReturnData
{
// Class is used to pass multiple data to the Ajax Call
public PageValues pageValues { get; set; }
public List<InputUser> users { get; set; }
}
So, I am expecting data to be passed, I just do not know why the server is not assigning the data. I am new at this and could use an experienced eye.
Thanks
Simply change your type from GET to POST in Ajax call.
I spent some more time researching everything about ajax return values and classes.
Ultimately, my class was malformed, once I changed that it started working. I also changed the type to POST, I did not want to use POST just to read records. But I am sending a lot of data keeping up with search, pagination and sorting.
The below code works though I feel like it is very verbose and some parts may be unnecessary. Hope it helps someone, and please feel free to comment and help me out on things that could help others.
<script>
// Class to use for ajax data
class pageValues {
constructor(){
this.sortColumn = ($("#inpSortColumn").val() == undefined) ? "LastName" : $("#inpSortColumn").val();
this.sortOrder = ($("#inpSortOrder").val() == undefined) ? "ASC" : $("#inpSortOrder").val();
this.filter = ($("#Filter").val() == undefined) ? "" : $("#Filter").val();
this.message = ($("#inpMessage").val() == undefined) ? "" : $("#inpMessage").val();
this.currentPage = ($("#inpCurrentPage").val() == undefined) ? 1 : $("#inpCurrentPage").val();
this.recordsPerPage = ($("#inpPageSize").val() == undefined) ? 5 : $("#inpPageSize").val();
this.totalRecords= ($("#inpTotalRecords").val() == undefined) ? 0 : $("#inpTotalRecords").val();
}
get SortColumn() { return this.sortColumn; }
set SortColumn(value) { this.sortColumn = value; }
get SortOrder() { return this.sortOrder; }
set SortOrder(value) { this.sortOrder = value;}
get Filter() { return this.filter; }
set Filter(value) { this.filter = value; }
get Message() { return this.message; }
set Message(value) { this.message = value; }
get CurrentPage() { return this.currentPage; }
set CurrentPage(value) { this.currentPage = value; }
get RecordsPerPage() { return this.recordsPerPage; }
set RecordsPerPage(value) { this.recordsPerPage = value; }
get TotalRecords() { return this.totalRecords; }
set TotalRecords(value) { this.totalRecords = value; }
}
$(document).ready(function () {
// If we are here, the browser allows JS
// So, replace the submit buttons with Ajax functions
ReplaceHtml();
});
function ReplaceHtml() {
// Search Button
var divSearch = $("#divSearchBtn");
divSearch.hide();
divSearch.empty();
divSearch.append('<button id="btnAjaxSearch" type="button" ' +
'class="" onclick="RequestRecords();">Search</button>');
divSearch.show();
}
// Here we call the Ajax function passing the data object and the callback function
function RequestRecords() {
alert($("#Filter").val()); // This is just to Verify value is present
AjaxCallForRecords(new pageValues(), ReturnedData);
}
// This is the callback funtion
function ReturnedData(data) {
// The verification we hit the callback
alert("inside ajax callback");
alert(data.users[0].firstName);
}
// Ajax function
function AjaxCallForRecords(dataToSend, callback) {
console.log(dataToSend);
$.ajax({
type: "POST",
url: '#Url.Action("Index_Ajax","ApplicationUsers")',
data: JSON.stringify(dataToSend),
dataType: "json",
contentType: "application/json",
success: function (data) { callback(data); },
error: function (data) { alert("Error. ResponseText: " + data.responseText); }
});
}
</script>

Handle all Ajax exceptions in one place and return error to view

I have a fairly large application with dozens of Ajax calls. I want to log any of the errors that come up in the ajax calls in one single place. I put a jquery alert on my _Layout.cshmtl view so that the exception can get passed into the alert. How do I return a error string from my HandleExceptionAttribute class to my view?
Controller Action:
[HandleExceptionAttribute]
[HttpPost]
[Authorize ( Roles = "View Only,Admin,A-Team Manager,A-Team Analyst" )]
public JsonResult GetEntitySorMapTable ( Decimal entityId )
{
//Added this line to hit my HandleExceptionAttribute
throw new DivideByZeroException();
List<EntitySorMapView> entitySorMaps = null;
if (entityId == 0)
{
entitySorMaps = new List<EntitySorMapView> ( );
}
entitySorMaps = RealmsModel.RealmsDataInterface ( ).SelectEntitySorMapByEntityId ( entityId );
String data = HtmlHelpers.BuildEntitySorMapTable ( entitySorMaps );
return new JsonResult ( )
{
Data = data,
MaxJsonLength = Int32.MaxValue
};
}
Error Attribute:
public class HandleExceptionAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
filterContext.Exception.Message,
filterContext.Exception.StackTrace
}
};
filterContext.ExceptionHandled = true;
}
else
{
base.OnException(filterContext);
}
}
}
_Layout View ajax error script:
<script type="text/javascript">
$(document).ajaxError(function (xhr, status, error) {
e.stopPropagation();
if (xhr.error != null)
alert('Error: ' + xhr.responseText + ' status: ' + status + ' Exception: ' + error);
});
</script>
You can use
filterContext.Result = new JsonResult
{
Data = new { errorMessage = "Your custom error message" },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
and in your _layout.cshtml file
$(document).ajaxError(function (event, jqxhr, settings, thrownError) {
if (jqxhr.error != null) {
var result = JSON.parse(jqxhr.responseText);
console.log(result.errorMessage)
}
});

can't find action only on live server, works fine in local server

A public action method 'AddPromoCode' was not found on controller
'Flazingo.Controllers.PositionController'. at
System.Web.Mvc.Controller.HandleUnknownAction(String actionName) at
System.Web.Mvc.Controller.ExecuteCore() at
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at
System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.b__5()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.b__0()
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.b__d() at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step,
Boolean& completedSynchronously)
Here is the ajax call:
$.ajax({
url: '/Position/AddPromoCode',
type: 'POST',
dataType: "json",
contentType: "application/json; charset:utf-8",
data: ko.toJSON(viewModel),
success: function(result){
if(result.TypeId == 1){
viewModel.promoOff(viewModel.grandTotal() * (result.Value / 100));
viewModel.PromoCodes.push(promoCode + ": "+ result.Value + "% off");
}else{
viewModel.PromoCodes.push(promoCode + ": "+ result.Value + "days free");
}
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
var errorData = jQuery.parseJSON(xmlHttpRequest.responseText);
var errorMessages = [];
//this ugly loop is because List<> is serialized to an object instead of an array
for (var key in errorData)
{
errorMessages.push(errorData[key]);
}
toastr.error(errorMessages.join("<br />"), 'Uh oh');
}
});
EDIT: POST METHOD
[HttpPost]
public ActionResult AddPromoCode(PaymentViewModel model)
{
List<string> errors = new List<string>();
try
{
var position = db.Positions.SingleOrDefault(x => x.PositionId == model.PositionId);
if (position != null)
{
var promo = db.Promotions.SingleOrDefault(x => x.Code.ToLower() == model.PromoCode.ToLower() && x.IsUserEntered);
if (promo != null)
{
var promoUsage = db.PromoCodeUsages.SingleOrDefault(x => x.PromotionId == promo.PromotionId && x.ClientId == position.Client.Id);
int used = 0;
if (promoUsage != null)
{
used = promoUsage.Used;
}
if (used < promo.QuantityUsage)
{
if (DateTime.Today >= promo.StartDate && DateTime.Today <= promo.EndDate)
{
position.PromoCodes.Add(new PositionPromoCode
{
PromotionId = promo.PromotionId
});
var clientPC = position.Client.PromoCodes.SingleOrDefault(x => x.PromotionId == promo.PromotionId);
if (clientPC != null)
{
clientPC.Used = used + 1;
}
else
{
clientPC = new PromoCodeUsage()
{
PromotionId = promo.PromotionId,
Used = used + 1
};
position.Client.PromoCodes.Add(clientPC);
}
db.SaveChanges();
Response.StatusCode = (int)HttpStatusCode.OK;
return Json(new { Value = promo.Value, TypeId = promo.PromotionTypeId });
}
else
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
errors.Add("Sorry seems like this promotion code has expired");
db.SaveChanges();
return Json(errors);
}
}
else
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
errors.Add("Sorry seems like you have already used this code, or its not applicable anymore!");
db.SaveChanges();
return Json(errors);
}
}
else
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
errors.Add(string.Format("Sorry we don't have '{0}' promocode in our system!", model.PromoCode));
db.SaveChanges();
return Json(errors);
}
}
Response.StatusCode = (int)HttpStatusCode.BadRequest;
errors.Add("We coudn't find this position in our system!");
db.SaveChanges();
return Json(errors);
}
catch (Exception ex)
{
logger.Log(LogLevel.Error, string.Format("{0} \n {1}", ex.Message, ex.StackTrace));
Response.StatusCode = (int)HttpStatusCode.BadRequest;
errors.Add("Sorry there was internal errors, flazingo.com has been notified.");
return Json(errors);
}
}
JSON Structure:
{"PositionTitle":"Testing B Syntax Error","PromoCode":"FREECB","FirstName":null,"LastName":null,"Address":null,"SuiteNumber":null,"PhoneNumber":null,"City":null,"State":null,"ZipCode":null,"CreditCardNumber":null,"ExperationMonth":null,"ExperationYear":null,"CCV":null,"ClientId":2,"CustomerProfileId":64277420,"PositionId":78,"EmailAddress":"jmogera#gmail.com","Years":[{"Selected":false,"Text":"2013","Value":"2013"},{"Selected":false,"Text":"2014","Value":"2014"},{"Selected":false,"Text":"2015","Value":"2015"},{"Selected":false,"Text":"2016","Value":"2016"},{"Selected":false,"Text":"2017","Value":"2017"},{"Selected":false,"Text":"2018","Value":"2018"},{"Selected":false,"Text":"2019","Value":"2019"},{"Selected":false,"Text":"2020","Value":"2020"},{"Selected":false,"Text":"2021","Value":"2021"},{"Selected":false,"Text":"2022","Value":"2022"}],"MonthList":[{"Selected":false,"Text":"Jan","Value":"01"},{"Selected":false,"Text":"Feb","Value":"02"},{"Selected":false,"Text":"Mar","Value":"03"},{"Selected":false,"Text":"Apr","Value":"04"},{"Selected":false,"Text":"May","Value":"05"},{"Selected":false,"Text":"Jun","Value":"06"},{"Selected":false,"Text":"Jul","Value":"07"},{"Selected":false,"Text":"Aug","Value":"08"},{"Selected":false,"Text":"Sep","Value":"09"},{"Selected":false,"Text":"Oct","Value":"10"},{"Selected":false,"Text":"Nov","Value":"11"},{"Selected":false,"Text":"Dec","Value":"12"}],"IsAddingNewCard":false,"HaveCardOnFile":true,"AddOns":[{"PositionId":78,"ProductId":2,"Description":"The heart and soul, we take you through the hiring process, start to finish and give you every tool you need to make a great hire along the way.","Price":39,"HasAdded":true,"AutoRenew":true,"Name":"Complete Hiring System","AddOnId":122}],"CreditCards":[{"CreditCardId":16,"LastFour":"1060","HolderName":"Barrett Kuethen","ExpDate":"/Date(1422766800000)/","IsDefault":true}],"CardOnFile":{"CreditCardId":16,"LastFour":"1060","HolderName":"Barrett Kuethen","ExpDate":"/Date(1422766800000)/","IsDefault":true},"PromoCodes":[],"__ko_mapping__":{"CardOnFile":{},"ignore":[],"include":["_destroy"],"copy":[],"observe":[],"mappedProperties":{"PositionTitle":true,"PromoCode":true,"FirstName":true,"LastName":true,"Address":true,"SuiteNumber":true,"PhoneNumber":true,"City":true,"State":true,"ZipCode":true,"CreditCardNumber":true,"ExperationMonth":true,"ExperationYear":true,"CCV":true,"ClientId":true,"CustomerProfileId":true,"PositionId":true,"EmailAddress":true,"Years[0].Selected":true,"Years[0].Text":true,"Years[0].Value":true,"Years[1].Selected":true,"Years[1].Text":true,"Years[1].Value":true,"Years[2].Selected":true,"Years[2].Text":true,"Years[2].Value":true,"Years[3].Selected":true,"Years[3].Text":true,"Years[3].Value":true,"Years[4].Selected":true,"Years[4].Text":true,"Years[4].Value":true,"Years[5].Selected":true,"Years[5].Text":true,"Years[5].Value":true,"Years[6].Selected":true,"Years[6].Text":true,"Years[6].Value":true,"Years[7].Selected":true,"Years[7].Text":true,"Years[7].Value":true,"Years[8].Selected":true,"Years[8].Text":true,"Years[8].Value":true,"Years[9].Selected":true,"Years[9].Text":true,"Years[9].Value":true,"Years":true,"MonthList[0].Selected":true,"MonthList[0].Text":true,"MonthList[0].Value":true,"MonthList[1].Selected":true,"MonthList[1].Text":true,"MonthList[1].Value":true,"MonthList[2].Selected":true,"MonthList[2].Text":true,"MonthList[2].Value":true,"MonthList[3].Selected":true,"MonthList[3].Text":true,"MonthList[3].Value":true,"MonthList[4].Selected":true,"MonthList[4].Text":true,"MonthList[4].Value":true,"MonthList[5].Selected":true,"MonthList[5].Text":true,"MonthList[5].Value":true,"MonthList[6].Selected":true,"MonthList[6].Text":true,"MonthList[6].Value":true,"MonthList[7].Selected":true,"MonthList[7].Text":true,"MonthList[7].Value":true,"MonthList[8].Selected":true,"MonthList[8].Text":true,"MonthList[8].Value":true,"MonthList[9].Selected":true,"MonthList[9].Text":true,"MonthList[9].Value":true,"MonthList[10].Selected":true,"MonthList[10].Text":true,"MonthList[10].Value":true,"MonthList[11].Selected":true,"MonthList[11].Text":true,"MonthList[11].Value":true,"MonthList":true,"IsAddingNewCard":true,"HaveCardOnFile":true,"AddOns[0].PositionId":true,"AddOns[0].ProductId":true,"AddOns[0].Description":true,"AddOns[0].Price":true,"AddOns[0].HasAdded":true,"AddOns[0].AutoRenew":true,"AddOns[0].Name":true,"AddOns[0].AddOnId":true,"AddOns":true,"CreditCards[0].CreditCardId":true,"CreditCards[0].LastFour":true,"CreditCards[0].HolderName":true,"CreditCards[0].ExpDate":true,"CreditCards[0].IsDefault":true,"CreditCards":true,"CardOnFile":true,"PromoCodes":true},"copiedProperties":{}},"addNewCreditCardValidationGroup":{"FirstName":null,"LastName":null,"Address":null,"City":null,"State":null,"CreditCardNumber":null,"ExperationMonth":null,"ExperationYear":null,"CCV":null,"errors":[]},"promoOff":0,"grandTotal":39}
Note: the call is made within a knockout click function.
Note: I have created another issue, thinking it was client side issue. This is related.
Uncaught SyntaxError: Unexpected token B on live but not local server
It can't find AddPromoCode so, there seems a url problem. You should add the application name at ajax code in server like url: '/ApplicationName/Position/AddPromoCode'.
You can also do this with url.action html helper, like:
// In layout or view:
#Html.Hidden("urlPrefix", Url.Action("", ""))
// In Javascript
var baseUrl = $("input#urlPrefix").val();
$.ajax({ url: baseUrl + '/Position/AddPromoCode', ...
The part Url.Action("", "") creates '/ApplicationName' part dynamically.

returning different javascript object from controller

my controller action:
[HttpPost]
public ActionResult AddPointAndCopyOtherSongToPlaylist(int id)
{
if (CheckIfAddPointToSelf(User.Identity.Name, id))
{
var song = repository.GetSong(id);
foreach (var item in song.Points)
{
if (User.Identity.Name == item.UsernameGavePoint)
{
var data1 = 1;
return Json(new {data1}, JsonRequestBehavior.AllowGet);
}
}
var originalSong = repository.GetSong(id);
var newSong = new Song();
newSong.UserName = User.Identity.Name;
newSong.Title = originalSong.Title;
newSong.YoutubeLink = originalSong.YoutubeLink;
newSong.GenreId = 38;
newSong.Date = DateTime.Now;
repository.AddSong(newSong);
var point = new Point();
point.UsernameGotPoint = originalSong.UserName;
point.UsernameGavePoint = User.Identity.Name;
point.Date = DateTime.Now;
point.Score = 1;
point.OtherSongId = id;
repository.AddPoint(point);
repository.Save();
int data = 2;
//process here
return Json(new { data }, JsonRequestBehavior.AllowGet);
}
else
{
return null;
}
}
based on different scenarios I want to return a javascript and somehow notify the client of what was returned and based in the result do something in the success part of my ajax call:
$.ajax({
beforeSend: function () { ShowAjaxLoader(); },
url: "/Home/AddPointAndCopyOtherSongToPlaylist/",
type: "POST",
data: { id: songId },
success: function (data,one) {
if (data && !one) {
HideAjaxLoader(), ShowMsg("Song Added Successfully");
}
else if(!data) {
HideAjaxLoader(), ShowMsg("you cannot add your own songs");
}
else if (data && one) {
HideAjaxLoader(), ShowMsg("You cannot add the same song twice");
}
},
error: function () { HideAjaxLoader(), ShowMsg("Song could not be added, please try again") }
});
});
I tried many different variations but I think i need something like data.property1 returned and in the client to check if that property exists or soemthing like that.. please help
You need to return your status code within the object.
return Json( new { data1 = "Some Other Data", status = 1} );
Then in your success handler check data.status.
if (data.status === 1) {
alert(data.data1);
}

Resources