I have multiple parameters which I have to pass to api controller.
What I was doing is
In my javascript
var routeInfo = JSON.stringify(routes);
var colors = JSON.stringify(colorsArray);
var times = JSON.stringify(mytimeArray);
var distances = JSON.stringify(myDistancArray);
var dir = $("#Direction").val();
var fullString = routeInfo + ";" + colors + ";" + times + ";" + distances+";"+dir;
$.post("api/HomeToSchool/?route=" + fullString,
function (data) {
if (data = true) {
alert("Routes Saved Successfully");
}
else if (data = false) {
alert("Routes are not saved");
}
});
& in my Controller
public bool PostHomeToSchoolRoutes([FromUri]string route)
{
// my logic
}
Here I am just getting values of "routeInfo" & other values are not comming.
e.g.
var routeInfo = [["Børge,Brogade 38, 4100, Ringsted,09:25:00,55.43953, 11.79043","Grete,Sjællandsgade 27, 4100, Ringsted,09:25:00,55.44024, 11.78852","Else,Fynsgade 14, 4100, Ringsted,09:25:00,55.44128, 11.78595","Birthe,Eksercerpladsen 47, 4100, Ringsted,09:25:00,55.44954, 11.80309","Knud Lavard Centret, Eksercerpladsen 3, 4100, Ringsted,370,55.45014, 11.80474"]]
var colors = ["#886A52"]
var times = [7.97]
var distances = [3.36]
var dir = 0
What I get in my Controller is
[["Børge,Brogade 38, 4100, Ringsted,09:25:00,55.43953, 11.79043","Grete,Sjællandsgade 27, 4100, Ringsted,09:25:00,55.44024, 11.78852","Else,Fynsgade 14, 4100, Ringsted,09:25:00,55.44128, 11.78595","Birthe,Eksercerpladsen 47, 4100, Ringsted,09:25:00,55.44954, 11.80309","Knud Lavard Centret, Eksercerpladsen 3, 4100, Ringsted,370,55.45014, 11.80474"]];["
Other values are not coming.
Whats wrong I am doing here.
I'm afraid that your url is too long (>255 characters), You can try this.
$.ajax({
type: 'POST',
url:"api/HomeToSchool",
data:{routeInfo:routes,colors:colorsArray,times:mytimeArray,distances:myDistancArray,dir:dir},
dataType: "json",
traditional:true,
function (data) {
if (data = true) {
alert("Routes Saved Successfully");
}
else if (data = false) {
alert("Routes are not saved");
}
}
});
and your controller:
public bool PostHomeToSchoolRoutes(string[] routeInfo,string[] colors,double[] times,double[] distances,int dir)
{
// my logic
}
I see that you're using 2-dimensional array for routeInfo. But there is only 1 item, i think you should change it to 1-dimensional array to make it compatible with the controller code string[] routeInfo
Far too much information going into the URL here, not only that your not correctly appending the parameters together they need to be separated using & not ;.
On top of that, your not really taking advantage of the MVC capabilities here. At the client side you want to send up your information as a collective object rather than individual parameters e.g.
var schoolRoutes = {
routes: routes,
colors: colorsArray,
times: mytimeArray,
distances: myDistanceArray,
direction: $("#Direction").val()
};
$.ajax({
type: 'POST'
url: "api/HomeToSchoolRoutes",
data: JSON.stringify(schoolRoutes),
dataType: "json",
success: function (data) {
if (data = true) {
alert("Routes Saved Successfully");
}
else if (data = false) {
alert("Routes are not saved");
}
});
Then at the server side, introduce a class which will be able to bind to the incoming data aka a ViewModel
public class RouteInfoViewModel
{
...
}
public class SchoolRoutesViewModel
{
public RouteInfoViewModel[] Routes { get; set; }
public string[] Colours { get; set; }
public double[] Times { get; set; }
public double[] Distances { get; set; }
public string Direction { get; set; }
}
Then update your action to expect this particular ViewModel and that should give you access to all the information posted.
public bool PostHomeToSchoolRoutes(SchoolRoutesViewModel schoolRoutes)
{
...
}
Related
I have 2 form that i want to post to controller using serialize concept at once. Is it possible to send more the one serialize form in one ajax to controller?
if it is, how can i do that?
this is my ajax/javascript:
$('#btnSave').click(function () {
debugger;
var vDataHead = $('#frmHeader').serialize();
var vDataDet = $('#frmDetail').serialize();
if ($("#txtCompanyID").val() == "" || $("#txtBranchID").val() == "" || $("#txtUserID").val() == "")
{
debugger;
Swal.fire('Error!', 'Please Fill All Fields to Save Budget Setting!', 'error');
}
else
{
debugger;
$.ajax({
url: '/MappingUserItemGroup/SaveData',
data: { dataHead: vDataHead, dataDet: vDataDet },
method: 'POST',
success: function (mdl)
{
debugger;
if (mdl == "Exist")
{
debugger;
Swal.fire('Error!', 'Setting Mapping User Item Group Already Exist ', 'error');
}
else if (mdl == "Berhasil")
{
debugger;
Swal.fire('Success', 'Setting Mapping User Item Group Was Successfully Saved!', 'success').then(() => { loadTable();});
}
else if (mdl == "Gagal")
{
debugger;
Swal.fire('Error!', 'Setting Mapping User Item Group Failed To Be Saved!', 'error');
}
},
error: function (mdl)
{
debugger;
}
});
}
});
and this is my controller:
public ActionResult SaveData(MapingUIGH dataHead, List<MapingUIGD> dataDet)
{
//do something here with that data serialize
}
You are passing two form values as an object so create a view model on server side that matches the object
public class MappingViewModel
{
public MapingUIGH DataHead { get; set; }
public List<MapingUIGD> DataDet { get; set; }
}
and use it as parameter to action method, so the format of data posted from UI matches with parameter
public ActionResult SaveData(MappingViewModel viewModel)
Ok, this might be simple, I'm having a simple $.post call to server sending string array as parameters..
$.get('/home/ReadCalPacTagValue', data, function (data) {
data = $.parseJSON(data);
if (data.length != 0) {
var ReadFromDb = data[0]["PushToDb"].replace('PushToDb','ReadFromDb');
var DBAckno = ReadFromDb.replace('ReadFromDb', 'DataAck');
var FIdTag = ReadFromDb.replace('ReadFromDb', 'FluidTypeId');
var UserIdTag = ReadFromDb.replace('ReadFromDb', 'UserId');
var UniqueIdTag = ReadFromDb.replace('ReadFromDb', 'UniqueRecordId');
var dbconnTag = ReadFromDb.replace('ReadFromDb', 'DatabaseConnectionString');
updateTags = [dbconnTag,FIdTag,ReadFromDb, UserIdTag,UniqueIdTag];
actionvalue = ["", fluidtypeid, '1', userid, uniqueID];
var data_Tags = { updateTags: updateTags, actionvalue: actionvalue }
$.post('/home/WriteCalPacTagValue', data_Tags, function (response) {
//var Path = "Config/16_CalPac/" + FluidType + "/" + metername + "/" + FileName
//$.cookie('FileName', FileName, { expires: 7, path: '/' });
//$.cookie('FilePath', Path, { expires: 7, path: '/' });
//$.cookie('ModuleName', "CalPac", { expires: 7, path: '/' });
//window.open('../home/CalPac', '_blank');
});
} else {
swal("Error !", "Data operation tag not binded for this product", "warning");
}
})
my problem is, every time it makes $.post call, server is getting null values int prarameters..
public void WriteCalPacTagValue(string[] updateTags, string[] actionValue)
{
string[] writetags = { };
DanpacUIRepository objNewTag = new DanpacUIRepository();
if (updateTags.Count() > 0)
{
actionValue[0] = ConfigurationManager.AppSettings["DBString"].ToString();
for (int i = 0; i < updateTags.Count(); i++)
{
writetags = updateTags[i].Replace("<", "").Replace(">", ">").Split('>');
objNewTag.WriteTag(writetags, actionValue[i]);
}
}
}
I'm not getting what I've done wrong here.. whereas same function is working from another JS file with some difference string into array updateTags.
any help?
Having
public class DataTags
{
public string[] UpdateTags { get; set; }
public string[] ActionValue { get; set; }
}
At the server: Change the method to this
[HttpPost()]
public void WriteCalPacTagValue([FromBody]DataTags data_Tags)
{
}
At the client: call it
$.ajax({
type: 'POST',
url: '/home/WriteCalPacTagValue',
data: data_Tags,
success: function (response) {
//your code
}
});
Also you can send the whole data as json string using data: JSON.stringify(data_Tags), in javascript code the change the WriteCalPacTagValue to accept a single string at the parameter and deserialize it in C# code at the server side.
EDIT if you cannot change the server side code, you may follow this as stated in the comments.
I would like to know how to convert the following object to C# when reaching the mathod. I needed to create an object which can hold multiple array's within JSON something like the following
{
"cars": {
"Ferrari":["LaFerrari","F40","458"],
"Porsche":["911","959"],
"Lamborghini":["Aventador"]
}
}
The code I used is the following within cshtml
<div class="row">
<div class="col-md-4">
<div>
<input type="text" id="txtKey" />
<input type="button" id="btnKey" />
</div>
<div>
<input type="text" id="txtChild" />
<input type="button" id="btnChild" />
</div>
<div>
<input type="button" id="btnSubmit" />
</div>
</div>
</div>
#section scripts
{
$(function () {
AddKeyToDictionary('Ferrari');
AddKeyToDictionary('Porsche');
AddKeyToDictionary('Lamborghini');
AddValueToDictionary('Ferrari', 'LaFerrari');
AddValueToDictionary('Ferrari', 'F40');
AddValueToDictionary('Ferrari', '458');
AddValueToDictionary('Porsche', '911');
AddValueToDictionary('Porsche', '959');
AddValueToDictionary('Lamborghini', 'Aventador');
$('#btnKey').click(function () {
AddKeyToDictionary($('#txtKey').val());
});
$('#btnChild').click(function () {
AddValueToDictionary($('#txtKey').val(), $('#txtChild').val());
});
$('#btnSubmit').click(function () {
submit();
});
});
var dict = {};
function AddKeyToDictionary(key) {
dict[key] = [];
}
function AddValueToDictionary(key, value) {
dict[key].push(value);
}
function submit() {
var url = "#Url.Action("UpdateCustomFields", "Home")";
var data = JSON.stringify({ 'cars': dict });
$.ajax({
type: "POST",
contentType: "Application/json;charset=utf-8",
url: url,
data: data,
datatype: "json",
success: function (msg) {
},
error: function (request, status, error) {
displayDialog("A communication Error has occurred, please contact IT support: " + error);
}
});
}
</script>
}
I've tried the following within MVC (got this from a JSON c# convertor)
public JsonResult UpdateCustomFields(RootObject cars)
{
return Json("");
}
}
public class Cars
{
public List<string> Ferrari { get; set; }
public List<string> Porsche { get; set; }
public List<string> Lamborghini { get; set; }
}
public class RootObject
{
public Cars cars { get; set; }
}
The car makes should be dynamic and then the arrays below should be converted correctly.
I also tried to iterate through the array and changed them all to key value pairs which still wasn't rendering
function convertToKeyValue() {
submitValue = [];
for (var k in dict) {
if (dict.hasOwnProperty(k)) {
if (dict[k].length > 0) {
for (var i = 0; i < dict[k].length; i++) {
submitValue.push({ key: k, value: dict[k][i] });
}
} else {
submitValue.push({ key: k, value: '' });
}
}
}
}
Passing them through the name/value pairs I was able to see them in the dynamic property within the controller but can't get to the variables.
public JsonResult UpdateClientCustomFields(object cars)
{
var result = customFields.XmlSerializeToString();
return Json("hello");
}
If anyone can help or point me in the right direction.
Thanks
Updated: I've had to convert the javascript array to a list of key pairs (not ideal) and use List> cars as the paramter, the model is not ideal, but will use this until I find a better way.
Here is the updated code
HTML
<input type="button" id="btnSubmit2" />
var submitValue = [];
function convertToKeyValue() {
submitValue = [];
for (var k in dict) {
if (dict.hasOwnProperty(k)) {
//alert("Key is " + k + ", value is" + dict[k]);
//alert("KEY: " + k);
if (dict[k].length > 0) {
for (var i = 0; i < dict[k].length; i++) {
//alert("childrec: " + dict[k][i]);
submitValue.push({ key: k, value: dict[k][i] });
}
} else {
submitValue.push({ key: k, value: '' });
}
}
}
}
function submit2() {
convertToKeyValue();
var url = "#Url.Action("UpdateCustomFields2", "Home")";
var data = JSON.stringify({ 'cars': submitValue });
$.ajax({
type: "POST",
contentType: "Application/json;charset=utf-8",
url: url,
data: data,
datatype: "json",
success: function (msg) {
},
error: function (request, status, error) {
}
});
}
MVC
public JsonResult UpdateCustomFields2(List<Dictionary<string, string>> cars)
{
return Json("");
}
Try changing your cars property in RootObject to public Dictionary<string,List<string>> cars {get; set;}
Try to make your input param as string and then deserialize it to your object.
public JsonResult UpdateCustomFields(string cars)
{
RootObject yourCars = JsonConvert.DeserializeObject<RootObject>(cars);
return Json("");
}
Good luck :)
Unless I am missing something, the following seems to work fine
public class Program
{
public void Main(string[] args)
{
var json = #"
{
""cars"": {
""Ferrari"":[""LaFerrari"",""F40"",""458""],
""Porsche"":[""911"",""959""],
""Lamborghini"":[""Aventador""]
}
}
";
var dataObj = JsonConvert.DeserializeObject<Data>(json);
}
public class Data
{
public Dictionary<string, List<string>> Cars { get; set; }
}
}
Which version of JSON.NET are you using? I remember older versions had issues with dictionaries, but you could probably just create your own converter if that is the case.
I m trying to call web method from jsTree but unable to call it. can someone please help me out to get this resolved.
my jsTree function is:-
$('#tree').jstree({
"json_data": {
"ajax": {
"type": "POST",
"dataType": "json",
"async": true,
"contentType": "application/json;",
"opts": {
"method": "POST",
"url": "../../SurveyReport/Metrics.aspx/GetAllNodes11"
},
"url": "../../SurveyReport/Metrics.aspx/GetAllNodes11",
"data": function (node) {
if (node == -1) {
return '{ "operation" : "get_children", "id" : -1 }';
}
else {
//get the children for this node
return '{ "operation" : "get_children", "id" : ' + $(node).attr("id") + ' }';
}
},
"success": function (retval) {
alert('Success')
return retval.d;
},
"error": function (r) {
alert(r.attr);
alert('error');
}
}
},
"plugins": ["themes", "json_data"]
});
And web method and data file is:-
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static List<G_JSTree> GetAllNodes11(string id)
{
if (id != "-1") //-1 means initial load else async loading of children
{
if (id == "10")
//Add 3 children to parent node with id=10.
return AddChildNodes(10, 3, "xxxx");
else
return new List<G_JSTree>();
}
List<G_JSTree> G_JSTreeArray = new List<G_JSTree>();
//Creating the JsTree data
//In live scenarios this will come from db or Web Service
//Add 5 root nodes
G_JSTreeArray.AddRange(AddChildNodes(0, 5, ""));
//Add 4 children to 3rd root node
//The third node has id=30
//The child nodes will have ids like 301,302,303,304
G_JSTreeArray[3].children = (AddChildNodes(30, 4, G_JSTreeArray[3].data)).ToArray();
//Add 5 children to level1 Node at id=302
G_JSTreeArray[3].children[1].children = (AddChildNodes(302, 4, G_JSTreeArray[3].children[1].data)).ToArray();
return G_JSTreeArray;
}
private static List<G_JSTree> AddChildNodes(int _ParentID, int NumOfChildren, string ParentName)
{
List<G_JSTree> G_JSTreeArray = new List<G_JSTree>();
int n = 10;
for (int i = 0; i < NumOfChildren; i++)
{
int CurrChildId = (_ParentID == 0) ? n : ((_ParentID * 10) + i);
G_JSTree _G_JSTree = new G_JSTree();
_G_JSTree.data = (_ParentID == 0) ? "root" + "-Child" + i.ToString() : ParentName + CurrChildId.ToString() + i.ToString();
_G_JSTree.state = "closed"; //For async to work
_G_JSTree.IdServerUse = CurrChildId;
_G_JSTree.children = null;
_G_JSTree.attr = new G_JsTreeAttribute { id = CurrChildId.ToString(), selected = false };
G_JSTreeArray.Add(_G_JSTree);
n = n + 10;
}
return G_JSTreeArray;
}
public class G_JSTree
{
public G_JsTreeAttribute attr;
public G_JSTree[] children;
public string data
{
get;
set;
}
public int IdServerUse
{
get;
set;
}
public string icons
{
get;
set;
}
public string state
{
get;
set;
}
}
public class G_JsTreeAttribute
{
public string id;
public bool selected;
}
}
I want to load the tree in an async fashion from a webmethod in an asp.net page.
Thanks in advance.
I use this Code Successfully By add this Complete Reference :
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)] //ResponseFormat.Json)]
public static List<GG_JSTree> GetAllNodes11(string id)
{......}
I am using a jQuery plugin, jTable. The plugin has the following function to load the table:
$('#PersonTable').jtable('load', { CityId: 2, Name: 'Halil' });
The values in the load function is send as POST data. The plugin also sends two query string parameters (jtStartIndex, jtPageSize) through the URL for paging the table.
An example in the documentation shows a function on how to handle this in ASP.NET MVC but not in Web API Example :
[HttpPost]
public JsonResult StudentListByFiter(string name = "", int cityId = 0, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
{
try
{
//Get data from database
var studentCount = _repository.StudentRepository.GetStudentCountByFilter(name, cityId);
var students = _repository.StudentRepository.GetStudentsByFilter(name, cityId, jtStartIndex, jtPageSize, jtSorting);
//Return result to jTable
return Json(new { Result = "OK", Records = students, TotalRecordCount = studentCount });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
How my function currently looks: It works fine except that I can't manage to read the POST data (name param):
public dynamic ProductsList(string name = "", int jtStartIndex = 0, int jtPageSize = 0 )
{
try
{
int count = db.Products.Count();
var products = from a in db.Products where a.ProductName.Contains(name) select a;
List<Product> prods = products.OrderBy(x => x.ProductID).ToList();
return (new { Result = "OK", Records = prods, TotalRecordCount = count });
}
catch (Exception ex)
{
return (new { Result = "ERROR", Message = ex.Message });
}
}
My jTable load: (This get called when the user enters text in a input)
$('#ProductTable').jtable('load', {
name: $('#prodFilter').val()
});
I would appreciate any help with how to read both the string parameters in the URL and the POST data in a Web API function.
EDIT:
I used an alternative way to send the data to the API. Instead of sending it in the load function formatted as JSON I used a function for the listAction and sent the data through the URL (See jTable API reference for details):
listAction: function (postData, jtParams) {
return $.Deferred(function ($dfd) {
$.ajax({
url: 'http://localhost:53756/api/Product/ProductsList?jtStartIndex=' + jtParams.jtStartIndex + '&jtPageSize=' + jtParams.jtPageSize + '&name=' + $('#prodFilter').val(),
type: 'POST',
dataType: 'json',
data: postData,
success: function (data) {
$dfd.resolve(data);
},
error: function () {
$dfd.reject();
}
});
});
}
To reload the table based on your filtered results:
$('#ProductTable').jtable('load');
Instead of this:
$('#ProductTable').jtable('load', {
name: $('#prodFilter').val()
});
Try applying the [FromBody] attribute to the name parameter
public dynamic GetProductList([FromBody]string name = "", int jtStartIndex = 0, jtPageSize = 0)
{
...
}
The default binder in Web API will look in the URI for simple types like string, specifying the FromBody attribute will force it to look in the body.