Using the following Viewmodel :
public class GetUsersFromNextCircuitRequest
{
public int? dosarId { get; set; }
public List<int> dosareIds { get; set; }
public string query { get; set; }
public int page { get; set; }
public int page_limit { get; set; }
}
and using it in the following action:
public ActionResult GetUsersFromNextCircuit(GetUsersFromNextCircuitRequest requestNextUsers)
{
}
and send the request the following way:
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: self.attr('getusersfromnextcircuiturl'),
dataType: "json",
contentType: 'application/json; charset=utf-8',
type: 'POST',
traditional: true,
data: function (term, page) {
if (self.attr('dosare') !== undefined && self.attr('dosare').length > 0) {
var dosareIds = [];
self.attr('dosare').forEach(function (element, index, list) {
dosareIds.push(element.attr('Id'));
});
return JSON.stringify({
query: term, // search term
page: page,
dosareIds: dosareIds,
page_limit: 30
});
}
else
return JSON.stringify({
query: term, // search term
page: page,
dosarId: self.attr('dosarid'),
page_limit: 30
});
},
results: function (data, page) {
var more = (page * 30) < data.total; // whether or not there are more results available
return { results: data.users, more: more };
}
}
The http request looks like this:
{"query":"xa","page":1,"dosareIds":[4137,4163],"pagelimit":30}
The problem is that the request parameter is null. I have no idea why it doesn't work.
We had the same problem, then we decided to use CustomModelBinder. Am sharing what we have done,
In client side,
In ajaxRequest u need to send the entire ViewModel as below,
var viewModel = new Object();
viewModel.query= term;
viewModel.page= page;
viewModel.dosareIds= new Array();
viewModel.dosarIds = dosareIds;
viewModel.page_limit = 30;
then stringify the model and assign it to the data,
data: { viewModel: JSON.stringify(viewModel) };
In Server side,
U can use customModelBinder to retrive the value back
public class CustomJsonModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
try
{
var data = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
JavaScriptSerializer js = new JavaScriptSerializer();
var temp = js.Deserialize(data.AttemptedValue, bindingContext.ModelType);
return temp;
}
catch
{
return null;
}
}
}
And in ur viewModel u need to add the attribute,
[ModelBinder(typeof(CustomJsonModelBinder))]
public class GetUsersFromNextCircuitRequest
{
public int? dosarId { get; set; }
public List<int> dosareIds { get; set; }
public string query { get; set; }
public int page { get; set; }
public int page_limit { get; set; }
}
Now, CustomJsonModelBinder will parse the value. I hope it will solve ur prob.
Related
I try to pass dynamic key value pair data from AJAX controller. Key and Value both are not fixed.
My AJAX call:
var lstJson = [];
$('#divjson').find('.jsonKeyValue').each(function(index, element) {
var key = $(this).find(".key").val();
var value = $(this).find(".value").val();
var lst = {};
lst.key = key;
lst.value = value;
lstJson.push(lst);
});
console.log(lstJson);
SecureAjaxCall.PassObject({
url: `${MyHostURL}/Localization/SaveJsonData`,
dataType: 'json',
data: JSON.stringify({
lstJson: lstJson
}),
success: function(data) {
alert('success');
}
});
Other AJAX parameter's like dataType: 'json',, type: 'POST',... comes dynamically that's not a problem.
When I see on devtool , It's post data:
{
"lstJson":[
{
"key":"create",
"value":"Banauhos"
},
{
"key":"btnGetstarted",
"value":"SuruGarnuhos"
},
{
"key":"titleOne",
"value":"Sirsak1"
},
{
"key":"data",
"value":"Tathyanka"
}
]
}
My controller:
[HttpPost]
public string SaveJsonData([FromBody] GetlocalizeValue lstJson)
{
// Other code to Save data but lstJson gives always null value
return "Success";
}
My getters and setters:
public class GetlocalizeValue
{
public List<GetlocalizeValue> lstJson { get; set; }
public string key { get; set; }
public string value { get; set; }
public string FilePath { get; set;
}
But I always get null value on my controller (lstJson is always null)? Any help is much appreciated.
Your model must reflect the json object structure:
public class KeysAndValues
{
[JsonPropertyName("key")
public string Key { get; set; }
[JsonPropertyName("value")
public string Value { get; set; }
}
public class LocalizedValues
{
[JsonPropertyName("lstJson")]
public KeysAndValues[] ListJson { get; set; }
}
It is recommended to follow c# property naming conventions by capitalizing the first letters, and provide a property name for json.
## AJAX CALL in cshtml page ##
function ValidateData() {
var editedRows = [];
$("#eventsTable tbody tr").each(function () {
editedRows.push({
PK_WS_Event: $(this).find("td:eq(1)")[0].innerText,
Act_Id: $(this).find("td:eq(2)")[0].innerText,
WeeklyStatus: $(this).find("td:eq(3) option:selected").text()
== "--Select--" ? "" : $(this).find("td:eq(3)
option:selected").text(),
WeeklyStatusSubType: $(this).find("td:eq(4)
option:selected").text() == "--Select--" ? "" : $(this).
find("td:eq(4) option:selected").text(),
AccountName: $(this).find("td:eq(5)")[0].innerText,
AccountNumber: $(this).find("td:eq(6)")[0].innerText,
WeeklyStatusDesc: $(this).find("td:eq(7)")
[0].textContent.trim(),
});
});
$.ajax({
type: 'post',
url: "/WeeklyStatus/IndexSubmit",
data: JSON.stringify({ editedRows: editedRows }),
contentType: 'application/json',
dataType: "html",
success: function (response) {
},
error: function (xhr, status, error) {
alert('fail');
}
});
}
## Server Code Controller and ##
----------
[HttpPost]
public IActionResult IndexSubmit(IList<WeeklyStatusEvents>
editedRows)
{
return null;
}
My ViewModel as like as below..
public class ReportViewModel
{
public int SelectedStatusId { get; set; }
public int SelectedSubTypeId { get; set; }
public List<WeeklyStatusEvents> statusEvents { get; set; }
}
And WeeklyStatusEvents model as shown below
public class WeeklyStatusEvents
{
public string PK_WS_Event { get; set; }
public string Act_Id { get; set; }
//public bool INDExcludeFromRpt { get; set; }
public string WeeklyStatus { get; set; }
public string WeeklyStatusSubType { get; set; }
public string AccountName { get; set; }
public string AccountNumber { get; set; }
public string WeeklyStatusDesc { get; set; }
}
So Here, I am getting count as 0......
I have created class with all these properties. and Same property name I was used in ajax call as well.
Even I am not getting data. Can you provide the solution what i missed to get the data.
Replace
data: JSON.stringify({ editedRows: editedRows }),
with
data: JSON.stringify(editedRows),
The difference is that you want to send an array of objects instead of an object which contains an array.
In order to see the diferences between those two, I recommend you to inspect what the following lines return:
console.log(JSON.stringify(editedRows)
console.log(JSON.stringify({ editedRows: editedRows })
And add [FromBody] in front of your parameter in your action.
Add [FromBody] in front of your List and try again
[HttpPost]
public ActionResult IndexSubmit([FromBody] List<WeeklyStatusEvents> obj)
{
Vreturn null;
}
I can't figure out why my action param is coming through null. I'm also not sure of how to even diagnose the issue. I can see the http request data being sent with data and stepping through the debugger shows the object as null, not sure how to see the steps in between.
Models
public class ComplexObj
{
public int Id { get; set; }
public int Test1 { get; set; }
public decimal Test2 { get; set; }
}
public class BiggerObj
{
public BiggerObj()
{
ComplexObj = new List<ComplexObj>();
}
public long OtherId { get; set; }
public string Name { get; set; }
public ICollection<ComplexObj> ComplexObjs { get; set; }
}
Action
[HttpPost]
public void TestAction(BiggerObj[] biggerObjs)
{
...// biggerObjs is null :(
}
View
function ajaxCall() {
var data = [];
var bigObj = new Object();
bigObj.OtherId = 123;
bigObj.Name = "TestName";
bigObj.ComplexObj = [];
var complexObj = new Object();
complexObj.Id = 789;
complexObj.Test1 = 123;
complexObj.Test2 = 456;
bigObj.ComplexObj.push(complexObj);
data.push(bigObj);
}
}
$.ajax({
url: SITEROOT + "myController/TestAction",
cache: false,
type: 'POST',
data: data,
complete: function() {
alert('done');
}
});
}
Solved
You must use:
JSON.stringify and declare the contentType as "application/json; charset=utf-8"
Parse the decimal value by using parseFloat() function, decimal is considered as int by default binder.
Change your Action to this:
[HttpPost]
public ActionResult TestAction(BiggerObj[] biggerObjs)
{
...// biggerObjs is null :(
}
Change your ajaxCall function to this:
//ajaxCall
function ajaxCall() {
var data = [];
var bigObj = {
OtherId : 123,
Name : "TestName",
ComplexObjs : new Array()
};
var ComplexObjs = {
Id: 789,
Test1: 123,
Test2: parseFloat(456)
// decimal types are considered an integer, you have to parse
};
bigObj.ComplexObjs.push(ComplexObjs);
data.push(bigObj);
$.ajax({
url:"/Test/TestAction",
cache: false,
type: 'POST',
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
complete: function () {
alert('done');
}
});
}
I tested, works fine.
function myItemsViewModel(ItemID, GroupID, ItemName, Quantity) {
this.ItemID = ItemID;
this.GroupID = GroupID;
this.ItemName = ItemName;
this.Quantity = Quantity;
}
And i have below code for posting to the controller
var CreateRecord = function () {
var Name = $.trim($("#divCreate").find("#txtName").val());
var Department = $.trim($("#divCreate").find("#txtDepartment").val());
var ItemsList = [];
$('#myDynamicTable').find('tr').each(function () {
var row = $(this);
var itemName = $.trim(row.find(".itemName input").val());
var itemQty = $.trim(row.find(".itemQty input").val());
var myItems = new myItemsViewModel("", "", itemName, itemQty);
ItemsList.push(myItems);
});
var obj = new myRecordEntryViewModel("", Name, Department, ItemsList);
var viewmodel = JSON.stringify(obj);
$.ajax({
type: 'POST',
cache: false,
dataType: 'html',
data: viewmodel,
headers: GetRequestVerificationToken(),
contentType: 'application/json; charset=utf-8',
url: '/' + virtualDirectory + '/RecordEntry/Save',
success: function (data) {
$("#divMaster").html(data);
return false;
},
error: function (msg) {
alert("Error Submitting Record Request!");
}
});
}
At the line var viewmodel = JSON.stringify(obj);, viewmodel has all the values that i want in my ItemsList array variable.
Problem is my ItemsList array is coming as null in the controller. Name and Department are coming through with the correct passed values.
Below is my controller code.
Class
public class myRecordEntryViewModel
{
public long ID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
public string[] ItemsList { get; set; }
}
Save action
[ActionName("Save")]
[NoCache]
public ActionResult Save(myRecordEntryViewModel viewModel)
{
//here viewModel.ItemsList is null, what could i be missing
if (this.SaveEntry(viewModel.Name,viewModel.Department,viewModel.ItemsList))
{
}
return this.View();
}
I'm wondering why viewModel.ItemsList is coming as null in controller yet it has values during the post from jQuery.
You should create a class for the Item in Item List (In C#)
public class Item {
public string ItemName { get; set; }
public int Quantity { get; set; }
}
And then change the viewmodel class
public class myRecordEntryViewModel
{
public long ID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
//public string[] ItemsList { get; set; }
public List<Item> ItemsList {get ; set;}
}
The controller can not map the Item List from your request into model because one is a list of string and other is a list of object.
There are several problems in your codes...
1) ItemList in your class and your javascript code are not same - The frist one is an array of strings, and the second is an array of objects
2) In your action method, you should change parameter type like the following:
public ActionResult Save(string viewModel)
3) In the body of your action method, you should deserialize the json string (viewModel) and make the model object from it. The following is an example...
https://stackoverflow.com/a/17741421/1814343
Try the below code and see if your model gets the values.
Let me know if you face any problems, because I've already implemented this in one of my projects
var CreateRecord = function () {
var Name = $.trim($("#divCreate").find("#txtName").val());
var Department = $.trim($("#divCreate").find("#txtDepartment").val());
var model="";
var ItemsList = [];
$('#myDynamicTable').find('tr').each(function () {
var row = $(this);
var itemName = $.trim(row.find(".itemName input").val());
var itemQty = $.trim(row.find(".itemQty input").val());
var myItems = new myItemsViewModel("", "", itemName, itemQty);
ItemsList.push(myItems);
});
model = ['Name' : Name , 'Department' : Department , 'ItemsList' :ItemsList];
$.ajax({
type: 'POST',
cache: false,
dataType: 'html',
data: JSON.stringify(model),
headers: GetRequestVerificationToken(),
contentType: 'application/json; charset=utf-8',
url: '/' + virtualDirectory + '/RecordEntry/Save',
success: function (data) {
$("#divMaster").html(data);
HideLoader();
return false;
},
error: function (msg) {
alert("Error Submitting Record Request!");
HideLoader();
}
});
}
I am currently working on a map function which requires me to display the data from the extracted JSON Response. This is the part of the class I get from my JSON response. I wish to extract 'text' from the JSON Response to display in the listbox.
public class Attributes
{
public double length { get; set; }
public double time { get; set; }
public string text { get; set; } //Want to display in listbox
public long ETA { get; set; }
public string maneuverType { get; set; }
}
public class rootobject
{
public Attribute attributes { get; set; }
public string compressedGeometry { get; set; }
}
I tried learning online but the data in the example are all hard-coded. Example of what I mean hard-coded:
Any help would be greatly appreciated.
Here is the sample method in WS web service.
[WebMethod]
public rootobject GetData()
{
var rootObj = new rootobject()
{
attributes = new Attribute[2] { new Attribute() { text = "text 1" }, new Attribute() { text = "text 2" } },
compressedGeometry = "geometry 1"
};
return rootObj;
}
JavaScript code to pull data from service
var webMethod = "WS.asmx/GetData";
var parameters = "";
$.ajax({
type: "POST",
url: webMethod,
data: parameters,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
$("#sel").html(msg.d);
var index = 0;
for (; index < msg.d.attributes.length; index++)
{
$("#sel").append("<option>" + msg.d.attributes[index].text + "<option>");
}
},
error: function (e) {
alert(e);
}
});
HTML for the drop down/ select
<select id="sel"></select>