cannot pass json object to mvc action - json

I am trying to call an mvc 3 action method with jquery ajax. please let me note that I am generating a partial view in ajax, and in the generated partial view, I am calling ajax again (it is something like nested ajax calls). here is my code:
the partial view:
#model MYWeb.UI.Models.ClientDetailsViewModel
The javascript in the view:
<script type="text/javascript">
$(document).ready(function () {
$("#savedetails#(i)").click(function () {
var clientNumber = $('#ClientNumber#(i)').val();
var clientName = $('#ClientName#(i)').val();
var client =
{
ClientNumber: clientNumber,
ClientName: clientName
};
alert(JSON.stringify(client));
$.ajax({
url: '/Home/ClientUpdate',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(client),
beforeSend: function () {
$("#loader#(i)_details").fadeIn('fast');
},
complete: function () {
$("#loader#(i)_details").fadeOut('fast');
},
success: function () {
$("#loader#(i)_details").fadeOut('fast');
if ($("#ModelFirstError").val())
showModelMessageError;
else
showUpdateMessageSuccess();
},
error: function () {
$("#loader#(i)_details").fadeOut('fast');
showUpdateMessageError();
},
async: true,
processData: false
});
});
});
the Model object:
public class ClientDetailsViewModel
{
[Display(ResourceType = typeof(adm), Name = "ClientNumber")]
public int ClientNumber { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessageResourceName = "RequiredClientName", ErrorMessageResourceType = typeof(adm))]
[Display(ResourceType = typeof(adm), Name = "ClientName")]
public string ClientName { get; set; }
more fields...
}
the action method:
[Authorize]
[HttpPost]
public ActionResult ClientUpdate(ClientDetailsViewModel client)
{}
this attempt to update always returns the ajax error. what am I doing wrong?
Edit:
I noticed that when I remove the parameter to the action method, it does get called.
But how can I pass the model this way?
[Authorize]
[HttpPost]
public ActionResult ClientUpdate()
{}

Related

Why do I get an empty parameter on the controller in my HttpPost method Ajax call?

I have a view that adds an Unordered list and list items to it at runtime, then I loop through to get the entered values, push the info to an object, and do the Ajax call to my method.
I always get an empty parameter on the controller, the console.log(assetWeighJsonDetail) shows what was entered, so I'm making sure I'm not passing and empty object (see the image below):
// Client side script:
var assetSerialNumber = "";
var weight = 0;
var assetWeighJsonDetail = [];
$(".ul-asset-weigh").each(function () {
var classNameSelected = this.id;
$("." + classNameSelected).each(function () {
assetSerialNumber = $(this).attr('id');
weight = $(this).val();
assetWeighJsonDetail.push({
OriginID: classNameSelected,
AssetSerialNumber: assetSerialNumber,
Weight: weight
});
});
});
console.log(assetWeighJsonDetail);
$.ajax({
url: "/AssetWeigh/SaveAssetWeigh",
data: JSON.stringify({assetWeighJsonDetail}),
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
traditional: true,
success: function (response) {
if (response) {
alert("success");
}
else {
alert("fail");
}
},
error: function (exception) {
}
});
// Console:
// Controller Method:
[HttpPost]
public ActionResult SaveAssetWeigh(List<AssetWeighJsonDetail> assetWeighJsonDetail)
{
bool success = false;
success = assetWeighJsonDetail != null && assetWeighJsonDetail.Count > 0;
return Json(success);
}
// Method's class List parameter:
public class AssetWeighJsonDetail
{
public int OriginID { get; set; }
public string AssetSerialNumber { get; set; }
public decimal Weight { get; set; }
}
You should try with $.post I have faced the same issue if using $.ajax and was not working and just switching to $.post made it work.
$.post( "/AssetWeigh/SaveAssetWeigh", parameters, function() {
alert( "success" );
})
.done(function() {
alert( "second success" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "finished" );
});
I'm on my phone and can't type all of it, I'll try to update later from my computer

How to send two JSON values from view to controller using EF

This is my script:
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
function btnadHocSave() {
debugger
var lv_header = $("#Header").serializeObject(); // this is header <fieldset> tag
var lv_detail = $("#SubmitMachine").serializeObject(); // this is detail <fieldset> tag
$.ajax({
type: "POST",
url: '#Url.Action("UpdateMachine")',
contentType: "application/json",
dataType: "JSON",
data: {
myheader: lv_header,
mydetail: lv_detail
},
cache: false,
success: function (data) {
alert("Success!..");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
}
})
}
This is my action code. PMAllotmentEntry and PMAllotmentDetailEntry are models:
public ActionResult UpdateMachine(PMAllotmentEntry myheader, PMAllotmentDetailEntry mydetail)
{
return View();
}
Now my problem I'm not able get the values from view to controller.
I tried JSON.stringify also but there is no use.
It is working If I pass single JSON value.
I tried out all the possibilities. Did as you said also but no use. Finally I did the following. I got two JSON values but still facing a issues because JSON second values first field value coming with first JSON values.
function btnadHocSave() {
debugger
var lv_header = $("#Header").serialize(); // this is header <fieldset>
var lv_detail = $("#SubmitMachine").serialize();
$.ajax(
{
type: "GET",
url: '/PMAllotments/UpdateMachine',
contentType: "application/json",
dataType: "JSON",
data: lv_header + ',' + lv_detail,
success: function (data) {
alert("Success!..");
debugger
$("#adHocAdd40").modal("hide");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
}
})
}
Now I'm removed JQuery from cshtml file and simply used post method
[HttpPost]
public ActionResult UpdateMachine(PMAllotmentEntry m)
{
//complete the task
return View();
}
replaced foreach loop in .cshtml file with for loop
FOR loop is highly important foreach loop never return your child model data.
#for (int a = 0; a < Model.PMAllotmentDetail.Count; a++)
{
#* table rows here *#
}
My Model as following
[NotMapped]
public class PMAllotmentEntry
{
[Key]
public Int64 PMAllotmentId { get; set; }
[Required (ErrorMessage ="Add atleast one machine!")]
public List<PMAllotmentDetailEntry> PMAllotmentDetail { get; set; }
}
[NotMapped]
public class PMAllotmentDetailEntry
{
[Key]
public Int64 PMAllotmentDetailId { get; set; }
[ForeignKey("PMAllotmentId")]
public Int64 PMAllotmentId { get; set; }
}

How to Serialize Model in View and Pass to Controller Action

I have a very specific need to serialize a model in the view and then pass it to a controller action at some point. I can get it to work by doing several hacks but its not pretty.
My test controller action
public ActionResult Index()
{
DefaultOptionValueRound defaultOptionValueRound = new DefaultOptionValueRound()
{
OptionId = 1835,
OptionValueId = 40343
};
TestModel testModel = new TestModel()
{
DefaultOptionValueRound = defaultOptionValueRound
};
return View(testModel);
}
The View
#using Common.Repository.Extensions
#model EngA.SandboxApplication.Controllers.TestModel
#Html.Hidden("DefaultOptionValueRound", Html.Raw(Json.Encode(Model.DefaultOptionValueRound)))
<input type="button" value="submit" onclick="SerializeModelTest.processOptionMag()"/>
<script language="javascript">
SerializeModelTest = {
processOptionMag: function () {
//Testing: This Works
//var defaultOptionValueRound = { OptionId: 1834, OptionValueId: 4034377 }
//var data = JSON.stringify({ defaultOptionValueRound: defaultOptionValueRound });
//This Does Not Work
var defaultOptionValueRound = $("#DefaultOptionValueRound").val();
var data = { defaultOptionValueRound: defaultOptionValueRound }; //Stringify Does not work either
$.ajax({
contentType: 'application/json; charset=utf-8',
type: "Post",
cache: false,
url: '#Url.Action("ProcessOptionMag", "SerializeModelTest")',
data: data,
dataType: "json",
traditional: true,
success: function(data) {
alert(data);
}
});
}
}
</script>
The problem is that the serialized model is returned in a stringify form already.
There must be an elegant way of doing this without me have to do JS string manipulation to make it work.
Thank you for your help
I found out that I can un-stringify my result using JSON.Parse and then repackage it with other parameters for sending to the controller.
var defaultOptionValueRound = $("#DefaultOptionValueRound").val();
var data = JSON.stringify({ defaultOptionValueRound: JSON.parse(defaultOptionValueRound) });
Now everything works.

knockout mapping of 3 dropdown lists using a JSON object containing 3 IList<CustomType>

Using Knockout I am trying to bind 3 dropdownlists with the data returned by an Ajax method calling a WebAPI.
The JSON data received is of Type "ReconDefMasters" where the calsses are defined as follows
public class MasterItem
{
public int MasterItemID { get; set; }
public string MasterItemName { get; set; }
}
public class ReconDefMasters
{
public IList<MasterItem> servFileFormat { get; set; }
public IList<MasterItem> mersRev { get; set; }
public IList<MasterItem> mersFileType { get; set; }
}
How to write the ko.mapping for this ?
I am able to achieve the result by returning IList, but then it requires 3 separate calls to the WebAPI- and trying to avoid this multiple calls by returning a composite object of 3 ILists.
I referred the below links , but not successful in modifying the logic for 3 dropdownlist together
http://jsfiddle.net/jearles/CGh9b/
Poblem with getting multidimensional array (object) observable in KnockoutJS
This is my code for single IList<> Method
var apipath = 'http://example.com';
ko.validation.init({
registerExtenders: true,
messagesOnModified: true,
insertMessages: false
});
function Master(data) {
var self = this;
self.FormatId = ko.observable(data.MasterItemID);
self.FormatName = ko.observable(data.MasterItemName);
}
var RuleDefVM = function (url) {
var self = this;
self.ServFileFormat = ko.observableArray();
self.selectedTemplate = ko.observable();
self.RuleDef = function () {
jQuery.support.cors = true;
$.ajax({
type: "GET",
url: url,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (response != "") {
$(response).each(function (index, element) {
self.ServFileFormat.push(new Master(element));
});
}
}
});
};
}
var urlRuleDef = apipath + '/api/RuleDef/';
var viewModelRuleDef = new RuleDefVM(urlRuleDef);
viewModelRuleDef.RuleDef();
function Master(data) {
var self = this;
self.FormatId = ko.observable(data.MasterItemID);
self.FormatName = ko.observable(data.MasterItemName);
}
selfDef.ServFileFormat = ko.observableArray();
selfDef.MERSRev = ko.observableArray();
selfDef.MERSFileType = ko.observableArray();
self.selectedTemplate1 = ko.observable();
self.selectedTemplate2 = ko.observable();
self.selectedTemplate3 = ko.observable();
jQuery.support.cors = true;
$.ajax({
url: url,
type: "GET",
dataType: "json",
contentType: "application/json; charset=utf-8",
cache: false,
success: function (response) {
if (response != "") {
$(response).each(function (index, element) {
$(element.servFileFormat).each(function (index,element) {
selfDef.ServFileFormat.push(new Master(element));
});
$(element.mersRev).each(function (index, element) {
selfDef.MERSRev.push(new Master(element));
});
$(element.mersFileType).each(function (index, element) {
selfDef.MERSFileType.push(new Master(element));
});
});
}
}
});
<select data-bind="options: ServFileFormat, value:selectedTemplate1, optionsText: 'FormatName' "class="dropdown"></select>
<select data-bind="options: MERSRev, value:selectedTemplate2, optionsText: 'FormatName' "class="dropdown"></select>
<select data-bind="options: MERSFileType, value:selectedTemplate3, optionsText: 'FormatName' "class="dropdown"></select>

return 2dimentional array to view from controller in Asp.Net MVC 3

I have a model which is: private int[,] mapTilesArray = new int[10, 10];
What I want to do is to use $.ajax to modify this model and then return it from controller
to my view. Then based on whatever values are inside this array I want to construct a similar array of divs in my view. So For now I don't know how to return this model to my view using json format.
my Ajax request:
var backgroundColor;
$(function () {
$(".mapTile").click(function () {
$("#info").text($(this).attr("x"));
var tile = {
X: $(this).attr("x"),
Y: $(this).attr("y")
};
$.ajax({
beforeSend: function () { ShowAjaxLoader(); },
url: "/Game/ShowTiles",
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(tile),
success: function (data) { HideAjaxLoader(); },
error: function () { HideAjaxLoader(); }
});
});
controller:
[HttpPost]
public ActionResult ShowTiles(TileModel tile)
{
MapModel map = new MapModel();
map.MapTilesArray[tile.X, tile.Y] = 1;
return this.Content(map.MapTilesArray.ToString());
}
So how would this be done the most efficient way? How would I recreate this array in my view?
A real quick and dirty solution could be the following, you might want to tweak it a bit here and there ;)
I'm assuming you already have like 225 divs representing cells on your page, with id's going from for example cell_1 to cell_225.
View :
$.ajax({
beforeSend: function () { ShowAjaxLoader(); },
url: "/Game/ShowTiles",
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(tile),
success: function (data) {
$.each(data, function (index, item) {
if (item) {
var cellnumber = ((item.Y * 15) + item.X);
$("#cell_" + cellnumber).innerText = item.Value;
}
});
HideAjaxLoader();
},
error: function () {
HideAjaxLoader();
}
});
Controller/Model :
public class MapModel
{
public TileModel[,] MapTilesArray;
public MapModel()
{
MapTilesArray = new TileModel[15, 15];
}
}
public class TileModel
{
public int X;
public int Y;
public int Value { get; set; }
}
[HttpPost]
public ActionResult ShowTiles(TileModel tile)
{
MapModel map = new MapModel();
map.MapTilesArray[tile.X, tile.Y] = new TileModel { X = tile.X, Y=tile.Y, Value = 1};
return Json(map.MapTilesArray);
}