Pass Multiple Parameters from Jquery to ASPX web method not working - javascript

I have one array which contain value in following format
var checkedvalue = [];
var x = "230";//Just now constant value pass
var y = "450";
checkedvalue.push({
xCordi : x,
yCordi : y,
bPart:txtName.value
});
in my code i have two button, 1 for push the TEXTBOX data in my array.
Now on second button click i want to pass this value to my web method and perform operation.
$AddtoDB.on('click', function () {
if ( $("#<%= divdynamicData.ClientID %>").is(':empty')){
alert("No Data Found");
}
else{
var ImageName="test.jpeg";
var ImagePath ="c:\drive";
IndertIntoDB(ImageName,ImagePath,checkedvalue);
}
});
the function is called when there is data.
function IndertIntoDB(ImageName,ImagePath,checkedvalue){
//alert(ImageName);
//alert(ImagePath);
//$.each( checkedvalue, function( key, value ) { alert( value.xCordi + ": " + value.yCordi +":"+ value.bPart );});
$.ajax({
type: "POST",
url: "ImageHotSpot.aspx/GetSaveData",
data: JSON.stringify({ iName: ImageName,iPath:ImagePath,iData:checkedvalue }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert("DataInserted");
}
});
Now i want to iterate the checkarray in web method but i got error.
//}
[System.Web.Services.WebMethod]
public static void GetSaveData(string iName, string iPath, string[] iData)
{
}

This answer is at first glance since i was not able to extract more info.
I hope this helps.
This is what your checkedvalue variable looks like in js code.
var checkedvalue = [];
var x = "230";//Just now constant value pass
var y = "450";
checkedvalue.push({
xCordi : x,
yCordi : y,
bPart:txtName.value
});
And this is your ajax request data.
data: JSON.stringify({ iName: ImageName,iPath:ImagePath,iData:checkedvalue })
Here is the method that is called with ajax.
public static void GetSaveData(string iName, string iPath, string[] iData)
Now i am not very familiar with ajax calling aspx. Usually there is a controller with MVC.
Since you don't mention the error in the original post.
My guess is you get a Null reference exception with checkedvalue->iData.
C# cannot deserialize a complex object from javascript without having the specifics. Meaning a c# object, it passes null.
An array of strings would work like this.
var checkedvalue = [];
checkedvalue.push("Hello"); //etc push other strings
You need a c# class like this one. Assuming they are of type string all three. From context i believe xCordi, yCordi are of type int feel free to change them. Also remove the "" from your js code.
public class SomeClass{
public string xCordi {get;set;} //change string to int
public string yCordi {get;set;} //change string to int
public string bPart {get;set;}
}
public static void GetSaveData(string iName, string iPath, string[] iData) -> public static void GetSaveData(string iName, string iPath, List<SomeClass> iData)
or public static void GetSaveData(string iName, string iPath, SomeClass[] iData)
Then your ajax method should work and c# should be able to deserialize the object.

Related

Pass array values from JavaScript to my MVC C# application

I would like to pass array values from javascript to my C#.
Currently I am getting GUID null in C#. Not sure where I am doing wrong.
When I check developer tool, I have values
http://localhost/mvc/CheckData?GUID[]=C71F952E-ED74-4138-8061-4B50B9EF6463&ColumnVal=1&RowVal=1
I would like to receive this GUID value in my C# code.
JavaScript
function CheckData(obj) {
$.ajax({
data: {GUID:eArray, ColumnVal: $('#DisColumn').val(), RowVal: $('#DisRow').val()},
url: "/mvc/CheckData",
cache: false,
success: function (result) {
....
}
});
}
C# backend code to receive values from front-end.
public ActionResult CheckData()
{
var GUID = HttpContext.Request["GUID"];
int columnVal = Convert.ToInt32(HttpContext.Request["ColumnVal"]);
int rowVal = Convert.ToInt32(HttpContext.Request["RowVal"]);
string result = (Services.CheckDataRecords(rowVal, columnVal,GUID)) ? "true" : "false";
return Content(result);
}
Currently, I am getting null when it hits to C# method var GUID = HttpContext.Request["GUID"];.
I can see array value in front-end. But it is somehow not passing that value.
HttpContext.Request represents the request, and to access query data, you will need to do something like this: HttpContext.Request.Query["GUID"].
A more straightforward approach is to let ASP.NET do the work for you is just turn your C# backend to this:
[HttpGet("CheckData")] //change the route based on your code
public ActionResult CheckData([FromQuery] Guid[] guid, int columnVal, int rowVal)
{
var GUIDs = guid;
int column = columnVal;
int row = rowVal;
.....//your code
}

passing an array from ajax call to controller, array empty in controller

Can anyone suggest what I need to change here?
I'm getting classes from elements that contain the class 'changed', the classes I get contain id's that I want to pass to the controller method.
When I look in the network tab I can see the data I want in the payload, it looks like this:
{"list":["GroupId-1","SubGroupId-2","changed"]}
but when I put a breakpoint on the controller the list is null.
This is the class I'm expecting in the controller method:
public class MemberGroups
{
public string GroupId { get; set; }
public string SubGrouId { get; set; }
public string Status { get; set; }
}
javascript for the save
function Savechanges() {
var spans = document.getElementsByClassName("changed");
var list = [];
$.each(spans,
function (key, value) {
$.each(value.classList,
function (key, value) {
list.push(value);
});
});
var dataToPost = JSON.stringify({ list: list });
$.ajax({
url: "/umbraco/Api/OrganisationMemberGroupsDashboardApi/UpdateMemberToGroup",
data: JSON.stringify({ list }),
type: "POST",
contentType: "application/json; charset=utf-8", // specify the content type
})
.done(function (data) {
});
}
controller
public string UpdateMemberToGroup( List<MemberGroups> list)
{
// save records
}
The spans are created dynamically and added to a treeview. When they are dragged and dropped all classes are removed then the 'changed' class is added along with the id classes so I only pass the ones I need to to the controller
var s = document.createElement('span');
s.classList.add('node-facility');
s.classList.add('ui-droppable');
s.classList.add('GroupId-' + value.GroupId);
s.classList.add('SubGroupId-0');
s.id=('GroupId-' + value.GroupId);
s.appendChild(document.createTextNode(value.GroupName));
This variant was tested using postman body json -
["GroupId-1","SubGroupId-2","changed"]
Change your ajax data to this:
data: list,
and your controller action:
public string UpdateMemberToGroup([FromBody] []string list)
{
var memberGroups = new MemberGroups
{
GroupId =list[0],
SubGrouId =list[1],
Status =list[2]
};
// save records
}
This variant was tested in postman using
{"GroupId":"GroupId-1","SubGroupId": "SubGroupId-2", "Status":"changed"}
you can put the code in javascript:
var data={GroupId:list[0],SubGroupId:list[1], Status:list[2]}
......
....
data:data,
.....
your controler action in this case:
public string UpdateMemberToGroup([FromBody] MemberGroups memberGroups)
{
// save records
}
And I don't know what version MVC you use , but for some versions instead of [FromBody] better to use [FromForm] or don't use anything at all.

Ajax success function not receive data

Below is webmethod of my web form which is returning a List of data and it works fine:
[WebMethod]
public static List<SalesInvoiceFinalCalculationEntity> salesInvoiceFinalCalculaiton(string InvoiceNo)
{
List<SalesInvoiceFinalCalculationEntity> list = new List<SalesInvoiceFinalCalculationEntity>();
list = SalesInvoiceManager1.salesInvoiceFinalCalculaiton(InvoiceNo);
return list;
}
But in below Ajax function, I can't retrieve the data. When I bind data to textbox in ajax success function, it displays Undefined text in Html textBox.
function salesInvoiceFinalCalculaiton() {
var InvoiceNo = $("#txt_InvoiceNo").val();
$.ajax({
async: false,
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/AjaxRequestToServer.aspx/salesInvoiceFinalCalculaiton", //URI
data: "{InvoiceNo:'" + InvoiceNo + "'}",
dataType: "json",
success: function (data) {
document.getElementById("txtinvoicevalue").value=(data.totalprice);
document.getElementById("txtTotalDiscount").value = data.discountamt;
document.getElementById("txtTotalTaxableValue").value = data.taxableamt;
document.getElementById("txtTotalCGST").value = data.cgstamt;
document.getElementById("txtTotalSGST").value = data.sgstamt;
document.getElementById("txtGrandTotal").value = data.grandtotal;
},
error: function (xhr) {
if (xhr.statusText == "Invalid Request") {
sessionStorage.clear();
}
}
});
}
Here is Data Layer and the stored procedure:
public static List<SalesInvoiceFinalCalculationEntity> salesInvoiceFinalCalculaiton(string InvoiceNo)
{
try
{
List<SalesInvoiceFinalCalculationEntity> SalesInvoiceFinalCalculation = new List<SalesInvoiceFinalCalculationEntity>();
DataSet ds = SqlHelper.ExecuteDataset(Util.ConnectionString, CommandType.StoredProcedure, "sp_salesInvoiceFinalCalculaiton",
new SqlParameter("#InvoiceNo", InvoiceNo));
foreach (DataRow dr in ds.Tables[0].Rows)
{
SalesInvoiceFinalCalculationEntity list = new SalesInvoiceFinalCalculationEntity(dr);
SalesInvoiceFinalCalculation.Add(list);
}
return SalesInvoiceFinalCalculation;
}
catch (Exception ex)
{
throw ex;
}
}
And this is my entity Class:
public class SalesInvoiceFinalCalculationEntity
{
public int InvoiceNo { get; set; }
float totalprice { get; set; }
float discountamt { get; set; }
float taxableamt { get; set; }
float cgstamt { get; set; }
float sgstamt { get; set; }
float grandtotal { get; set; }
public SalesInvoiceFinalCalculationEntity() { }
public SalesInvoiceFinalCalculationEntity(DataRow dr)
{
InvoiceNo = Convert.ToInt32(dr["InvoiceNo"]);
totalprice = float.Parse(dr["totalprice"].ToString());
discountamt = float.Parse(dr["discountamt"].ToString());
taxableamt = float.Parse(dr["taxableamt"].ToString());
cgstamt = float.Parse(dr["cgstamt"].ToString());
sgstamt = float.Parse(dr["sgstamt"].ToString());
grandtotal = float.Parse(dr["grandtotal"].ToString());
}
}
why is data is not received in success function!
First of all, using async: false it is a bad practice because it's freeze your window during to your request. Don't use it.
The issue is that you have to return a json object from your server-side method in order to receive response in success callback function of your ajax method.
[WebMethod]
public static string salesInvoiceFinalCalculaiton(string InvoiceNo)
{
List<SalesInvoiceFinalCalculationEntity> list = new List<SalesInvoiceFinalCalculationEntity>();
list = SalesInvoiceManager1.salesInvoiceFinalCalculaiton(InvoiceNo);
return JsonConvert.SerializeObject(list);
}
Web requests work with json format.
Finally resolved it. I forgot to mentioned
Public
in
SalesInvoiceFinalCalculationEntity
entity all variables and document.getElementById("txtinvoicevalue").value=(data.d[0].totalprice); this should be instead of
document.getElementById("txtinvoicevalue").value=(data.totalprice);
I think the problem is, that you're trying to send a Java Class to your JavaScript file. You can only send simple data types numbers, letters. As I understand, you're trying to access the member variables of SalesInvoiceFinalCalculationEntity.
If that's the case, you need to send it as a JSON object and get the data like this and then parse it.
The idea behind AJAX is to make the experience for the user better by not freezing the website using asynchronous requests. By calling the AJAX call with
async: false
removes the idea behind AJAX. You could then simply make a normal call to the server.
Use this:
https://www.newtonsoft.com/json
Serialize your list and return it as a string.
Then, in your javascript:
success: function (data) {
data = JSON.parse(data);
document.getElementById("txtinvoicevalue").value=(data.totalprice);
document.getElementById("txtTotalDiscount").value = data.discountamt;
document.getElementById("txtTotalTaxableValue").value = data.taxableamt;
document.getElementById("txtTotalCGST").value = data.cgstamt;
document.getElementById("txtTotalSGST").value = data.sgstamt;
document.getElementById("txtGrandTotal").value = data.grandtotal;
},
Try
success: function (data.d) rather than success: function (data). If I recall when using webmethods the return object is within data.d and not simply data.
Also, despite what other answers say. When using the [webmethod] attribute and jquery ajax, you do not have to convert your response object to json. It will do so automatically.

Ajax with formData dose not bind child's array of objects in asp.net controller

Hi I am trying to send files and some object in ajax call, using form data
here is my ajax call
$.ajax({
type: "POST",
url: "/Post/SharePost",
processData: false,
contentType: false,
headers: getAjaxHeaderWithToken(),
dataType: "json",
data: getDataToPost(),
});
here is my getDataToPost() method
function getDataToPost() {
var dataToPost = new FormData();
for (var i = 0; i < savedPictures.length; i++) {
var savedPictureToPost = { PictureId: savedPictures[i].PictureId};
dataToPost.append("vm.SavedPictures[" + i + "]", JSON.stringify( savedPictureToPost));
}
}
here is my controller
[HttpPost]
[ValidateAntiForgeryTokenOnAllPosts]
public ActionResult SharePost(SharePostVM vm, IEnumerable<HttpPostedFileBase> unsavedPictures)
{
}
and here is my SharePostVM
public class SharePostVM : BasePostVM
{
public SharePostCategories SharePostCategories { get; set; }
[Required]
public decimal? Price { get; set; }
[Required]
[Display(Name = "Available Date")]
public string DateAvailableFrom { get; set; }
public IEnumerable<PictureVM> SavedPictures { get; set; }
}
As you can see in my controller, I need to send files as well, but I just exclude the method for making it simple. Basically, I need to send files and object with an array of object. I can bind files and the property of SharePostVM like price and DateAvailableFrom by appending like dataToPost.append("vm", "priceValue"), but I can't bind the SavedPictures in SharePostVM. How can I bind them? I know I can retrieve from Request on server side but I just want to know if i can bind them. I have also tried without JSON.stringfy() but it still does not work..
Thanks guys
Try like this:
var pictureId = savedPictures[i].PictureId;
dataToPost.append("SavedPictures[" + i + "].PictureId", pictureId);
// ... and so on if you want to bind other properties than PictureId
Also in the getDataToPost function that you have shown in your question there's no return statement but I guess this is just a typo here and in your actual code the function returns a value.

ASP.NET MVC - How to "reverse" model binding to convert a C# model back to a query string representation

I have a custom javascript on the client side that I use to build up a querystring and pass over to my asp.net-mvc controller
var templateQueryString = BuildTemplate();
$.ajax({
url: '/MyController/Save?' + templateQueryString,
type: 'post',
dataType: 'json',
success: function (data) {
}
}
and on my controller all of the properties leverage the model binding so it comes in as a single object on the server side. NOTE: that this is a pretty complex object with arrays and arrays of sub objects:
public ActionResult Save(MyTemplate template)
{
}
the issue now is that I need to be able to convert from my C# object back to a string that represents "myTemplateQueryString" on the client side.
Is there any recommended way to take an object and do the "reverse" model binding. They key here is that it generates a string that I could use as a query string again in the future to pass into another asp.ent-mvc controller action.
Here is an example of the querystring that I am storing locally:
<input type="hidden" value="showIds=false&showRisks=false&
amp;statusIds=2&statusIds=1&statusIds=6&statusIds=8&
amp;statusIds=3&statusIds=9&showCompleted=0"
name="filterQueryString" id="filterQueryString">
As #haim770 said it would be easier if you used JSON in the request payload, and not the query string to pass your complex object to the server.
Regarding creating the query string from a model there is not a built-in method that does something like that or any recommended approach as far as i know. An obvious solution is to use reflection and build the query string from your properties.
Assuming your BuildTemplate class looks something like:
public class BuildTemplate
{
public bool ShowIds { get; set; }
public bool ShowRisks { get; set; }
public bool ShowCompleted { get; set; }
public int[] StatusIds { get; set; }
}
You can develop an extension method to convert any object to a QueryString. Here is some initial code you can start with:
public static class ObjectExtensions
{
public static string ToQueryString(this Object obj)
{
var keyPairs = obj.GetType().GetProperties().Select(p =>
new KeyValuePair<string, object>(p.Name.ToLower(), p.GetValue(obj, null)));
var arr = new List<string>();
foreach (var item in keyPairs)
{
if (item.Value is IEnumerable && !(item.Value is String))
{
foreach (var arrayItem in (item.Value as IEnumerable))
{
arr.Add(String.Format("{0}={1}", item.Key, arrayItem.ToString().ToLower()));
}
}
else
arr.Add(String.Format("{0}={1}", item.Key, item.Value.ToString().ToLower()));
}
return "?" + String.Join("&", arr);
}
}
Then you can easily invoke this code on any object to generate a query string:
var person = new BuildTemplate() { StatusIds = new []{ 1, 5, 8, 9 }, ShowRisks = true };
var queryString = person.ToQueryString();
This would generate a query string like:
"?showids=false&showrisks=true&showcompleted=false&statusids=1&statusids=5&statusids=8&statusids=9"
This query string should work just fine with the default model binder for the BuildTemplate class.

Categories

Resources