Passing JS array of objects to MVC controller without using a Model - c#

I'm attempting to centralize one of the features in our application. Throughout the site we have a numerous areas where a user can export a table (Syncfusion Grid) as excel. One issue we have is that every time a user filters/sorts to maintain the new table data layout, in the event the user does want to export, we have to make a round trip to the server, poke the DB and run an accompanying script. The alternative to this is we send out the filtered columns each time the user filters or on the export request.
I'm currently trying to switch all these round trips in the latter most option of only sending the data when the request is made to alleviate some of the back and forth. What I'd like to do is be able to send every grid to a single Controller which from the data can figure out what columns to show. Every case I can find so far if a Controller accepting a List<MODELNAME> but if I follow this case I'm not sure if it will work. I imagine I could create a generic export model which will accept the properties. The caveat to this is that these tables are driven by the DB to limit the effort required to modify them if a requirements change. Requirements are set by the reporting agencies our clients report to, neither us nor our clients so we never really know what will change. Changing the tables returned in the stored procedure automatically updates the table on the front. This would mean a change to the DB would need a subsequent update to the model if the property didn't previously exist.
Enough background, I'm trying to sent a generic array to the MVC controller, during the POC I'm using an already existing feature and trying to modify it.
public void ExportAlertListToExcel(string name, List<object> grid, string ignore = "")
The data is sent to the server using the ajax below using jQuery
$.ajax({
url: _url,
type: "POST",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ 'name': "Filler", 'grid': dataexport }),
success: function (data) {
// Do something neat
},
complete: function () { },
error: function (e) {
console.log(e);
}
});
The data will look something like
[
{name: 'One', age: '10'},
{name: 'Two', age: '12'},
{name: 'Three', age: '14'},
{name: 'Four', age: '16'},
]
But when it hits the controller it the values will come back as just {object}, regardless of using List, Array, or IEnumerable. I've tried not stringifying the data being sent and stringifying the array of objects inside the array. In cases where I get the data up its a string which I just cannot convert to an object where I can access the data values per item sent. I feel this should be something trivial but I cannot seem to be able to wrap my head around how to go about it. I've tried serializing, deserialzing, passing strings to try an access the data.

you have two primitive type parameter and one composite you may use custom route for your action like :
controller/action/{name}/{ignore}
and then reorder your parameter :
public void ExportAlertListToExcel(string name , string ignore = "",object grid)
$.ajax({
url: 'contrller/action?name=filler&ignore=c',
type: "POST",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: dataexport,
success: function (data) {
// Do something neat
},
complete: function () { },
error: function (e) {
console.log(e);
}
});
after retrieving the object in your code cast it to list of object and work on it.

JSON array data type is string. Did you try this ?
public void ExportAlertListToExcel(string grid)
$.ajax({
url: 'contrller/action?name=filler&ignore=c',
type: "POST",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: dataexport,
success: function (data) {
// Do something neat
},
complete: function () { },
error: function (e) {
console.log(e);
}
});

Try this, I have it working and binding as my custom object array in my controller
$('#costRowAdd').click(function () {
var shipmentCost = {
CarrierName: $("#AgentCarrierID").val(),
CostName: $("#ShipmentCostLineItems option:selected").html(),
Quantity: $("#ShipmentCostqty").val().replace(',', ''),
Rate: $("#ShipmentCostrate").val().replace('$', '').replace(',', ''),
EstimatedCost: $("#ShipmentCostcharge").val().replace('$', '').replace(',', '')
}
var shipmentCosts = [];
shipmentCosts.push(shipmentCost);
$.ajax({
url: 'AddShipmentCosts',
type: 'POST',
dataType: 'json',
data: { ShipmentCosts: shipmentCosts, ShipmentNumber: $('#ShipmentNumber').val() },
success: function (data) {
LoadShipmentCosts($("#ShipmentNumber").val());
$("#ShipmentCostqty").val('');
$("#ShipmentCostrate").val('');
$("#ShipmentCostcharge").val('');
}
});
return false;
});

Related

Ajax Webmethod not being called

I make a total of four Ajax calls in my .NET application. Three of them work without a hitch except the last one.
Note: I HAVE to use .aspx for these calls and not mypage.aspx/mymethod because of our architectural constraints.
Ajax call that works:
$.ajax({
type: "POST",
url: "myaddress/GenerateOpinionHTML.aspx",
data: JSON.stringify({ id: featureId, pageNumber: pageNumberIndex }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
SOME PROCESSING (IT WORKS)
},
error: function (xhr, status, error) {
var err = xhr.responseText;
console.log(err);
}
});
and
[WebMethod]
public static string GenerateOpinionHTML(int id, int pageNumber)
{
// ...
}
Ajax call that does not work:
console.log("SUBMITOPINIONCLICK");
var param = " ";
$.ajax({
type: "POST",
url: "myaddress/SaveOpinion.aspx",
data: JSON.stringify({ parameter: param}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
console.log("SAVE OPINION SUCCESSFUL");
console.log(msg.d);
CloseLB('GiveOpinionLB');
},
error: function (xhr, status, error) {
var err = xhr.responseText;
console.log("ERROR " + "STATUS: " + status);
}
});
and
[WebMethod]
public static string SaveOpinion(string parameter)
{
// ...
}
The web method SaveOpinion is never called according to the logs. Do you have any ideas or suggestions? I tried adding parameters, without parameters, checking my web.config file (though I shouldn't have since the other calls work)...
The error I get on the browser console is a "parseerror". I'm certain I wouldn't be getting an error if the method was called.
I think your URL should be like
url: "Your FolderName/PageName/Function Name",
Like
url: "myaddress/SaveOpinion.aspx/SaveOpinion"
but in your code this is different so that please check.
Have you checked if method SaveOption return something to the client?
If you specify dataType as json, you should return (at least): {}
Ok so we "solved" it. We just found a very dirty band-aid workaround that works.
We made a custom handler (.ashx) that we defined in our architecture as a SaveOpinion.aspx page.
We then called this custom handler page with jQuery and voilĂ  it works, we had to obviously pass all necessary parameters manually, ie. fetching all values from textBoxes etc with jQuery and not from the context as we did before.
Since this is run in some sort of thread (I don't really know the details) we had to configure it so that it simulates the same user authentification.
Anyway I hope this provides some measure of guidance for those with this kind of obscure problems.

Pnotify Post message via webservice

I'm fairly new to the programming world of Jquery.
I am trying to get data from a web service to be viewed on a notification via Pnotify.
However, on each page load the script does not view the notification bar. I really don't understand what I'm doing wrong. Hope you can help.
NOTE: the web service does retrieve the data correctly in JSON format.
UPDATED: I am able to do a msg.d but it retrieves the JSON but does not parse the information how I would like it to.
<script type="text/javascript">
$(function () {
$.ajax({ //DATA REQUEST
type: 'POST',
url: 'WebServices.asmx/getNote',
contentType: "application/json; charset=utf-8",
dataType: 'json',
success: function (msg) {
$.pnotify({ //CALL PNotify
title: msg.NoteTitle,
text: msg.NoteText
});
}
});
});
</script>
I reviewed your code and if you do the following you should be able to get the data you need.
You need to be aware that object that always need to be parsed before passing the array to a view.
In your case you didn't do that.
success: function (msg) {
var Obj= eval(msg["d"]); or // $.parseJSON(msg["d"]) Method to evaluate Json
$.pnotify({ //CALL PNotify
title: Obj["0"].NotificationText, // The pared arrays
text: Obj["0"].NotificationDescription

Passing a Var and List to Controller via Ajax

I have a Text Box and a Select Options Multiple, i store all the selected items using knockout selectedOptions in a viewModel.
If I try to pass the captured information to my Controller using ajax I'm unable to recieve my MetricsChosenModel.
var MetricsChosenModel= window.vm.MetricsChosenModel();
var ApplicationsNameValue = $.trim($("#add-Applications").val());
if (ApplicationsNameValue.length <= 0) {
$("#text-add-Applications").popover('show');
}
$.ajax({
url: '/Admin/AddApplications',
type: "POST",
dataType: "JSON",
data: { ApplicationsName: ApplicationsNameValue, MetricsChosenModel: MetricsChosenModel },
success: function (returndata) {
if (returndata == true) {
}
else {
}
},
error: function () {
}
});
My Controller
public ActionResult AddApplications(string ApplicationsName,List<string> MetricsChosenModel)
{
//Code here
return View();
}
My MetricsChosenModel stores data in following format
MetricsChosenModel[0] => 5
MetricsChosenModel [1] => 6
why am i not able to recieve the list value of MetricsChosenModel , I'm able to recieve the ApplicationsName though,
Also it would be great if some one can explain, how am i wrong here,
Thanks,
Without knowing what your routing looks like, it's hard to pinpoint the exact source of the problem. If I had to guess, I'd say that you're getting the ApplicationsName value through the URL (routing or querystring parameter). If that's the case, you could probably add the [FromBody] attribute to the MetricsChosenModel. Note, however, that you're only allowed one FromBodyAttribute per method signature. If you need more variables, a simple solution to this problem is to create a model which contains each of the properties you're looking to receive in your controller action.
Hope that helps!
I've run into this problem myself with ASP.NET MVC: sending a model with some fields and one or more arrays up to a controller would not properly get the array contents into the C# model. The following change to the ajax call fixes it for me every time:
$.ajax({
url: '/Admin/AddApplications',
type: "POST",
contentType: 'application/json; charset=utf-8', // ADD THIS
dataType: "JSON",
data: JSON.stringify({ ApplicationsName: ApplicationsNameValue, MetricsChosenModel: MetricsChosenModel }), // Also added JSON.stringify
success: function (returndata) {
if (returndata == true) {
}
else {
}
},
error: function () {
}
});
The 'content-type' and 'JSON.stringify' help MVC with converting the model. Please let me know if that helped for you too :)

Pass a collection to MVC controller via jquery

I'm using ASP.NET MVC3 with Jquery. I'm trying to pass my form elements back to the controller using something like this (Please note I removed success and error code for simplicity):
var formElements = $("#myForm").serialize();
$.ajax({
type: "POST",
url: ScriptResolveUrl("~/Report/SubmitChanges"),
data: {collection: formElements},
success:
error:
dataType: "json"
});
My question is what should the parameter in my controller method look like:
Here is my controller method:
public ActionResult SubmitChanges(WHAT GOES HERE?)
{
}
So what I'm really looking for is what should be the type of the parameter going into the controller method? I want to be able to retrieve the values of the form elements in the controller.
So here is what I did. I have about 20-30 elements on my form so I really didn't want to have to turn each one into a parameter or list them all out in the collection.
In the jquery, I did the following:
var formElements = $("#myForm").serialize();
$.ajax({
type: "POST",
url: ScriptResolveUrl("~/Report/SubmitChanges"),
data: { parms: formElements },
success:
error:
dataType: "json"
});
It then goes into my controller as a string:
public ActionResult SubmitChanges(string parms)
I then found a function to parse that string (seems to be working)
NameValueCollection qscoll = HttpUtility.ParseQueryString(parms);
This seems to work without listing out all of the form elements.
Assuming your form elements all correspond to your model (let's say it's MyModel), then it should simply be:
public ActionResult SubmitChanges(MyModel model)
{
}
MVC default model binding will do the rest :).
Make sure you change your data definition in the jQuery ajax method though, you've already serialized it. Just do:
data: formElements,
I'm assuming the following in your jQuery ajax method is a copy and paste error?
success:
error:
If it's not, then make sure you either remove it, or change them to:
success: function (result) {
//do something
},
error: function () {
//do something on error
}
The problem is that their is no model that corresponds to my form
elements.
Then you can have this:
public ActionResult SubmitChanges(int id, string name)
{
}
And then pass in the individual items:
var o = {
id = $("#id_elem_id").val(),
name = $("#name_elem_id").val()
}
$.ajax({
type: "POST",
url: ScriptResolveUrl("~/Report/SubmitChanges"),
data: JSON.stringify(o),
success:
error:
dataType: "json"
});
where id_elem_id and name_elem_id are the ids of your html elements. And add any additional parameters you need, just follow along.
You were almost there. Just get rid of the brackets around your data parameter:
var formElements = $('#myForm').serialize();
$.ajax({
type: 'POST',
url: ScriptResolveUrl("~/Report/SubmitChanges"),
data: formElements,
success: function(result) {
// handle the success of the AJAX request
},
error: function() {
// an error occurred
}
});

How can I deserialize in the website the string contained in the result.d of an ajax call?

This is a simplified flow, but it will be easier to explain:
I have an application which calls an webmethod using JQuery, it gets the returning value and stores in a hidden field so this can be accessed by the code behind once a postback is made.
I have the following code:
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ contacts: _contacts }),
dataType: 'json',
url: '/MyPage.aspx/MyMethod',
success: function (result) {
hdn.val(result.d);
}
});
In my code behind I try to get this information and parse it:
protected void btnRegister_Click(object sender, EventArgs e)
{
ContactInfo[] importedContacts = new JavaScriptSerializer().Deserialize<ContactInfo[]>(this.hdContacts.Value);
}
But I get an exception saying:
Value cannot be null. Parameter name: type
I figured out the the problem is this _Type parameter, which doesnt exist in my ContactInfo object.
I am wondering how I can deserialize this information. This should be easily deserializable because it comes directly from my ajax call.
Edit: about the "type" parameter: it is added automatically by the .NET Framework in order to serialize the return object for the WebMethod MyPage.aspx/MyMethod. I imagined that if the framework adds this information when serializing the data, I could use the same serializer to deserialize it....
In the hdnValue I have the following string:
[{"__type":"Un.Socialize.ContactInfo","ID":"123","FirstName":"First","LastName":"Last","FullName":"First Last","EMail":"email#email.com","Nickname":"Nick","Picture":"Pic.jpg","AlreadyExists":false}]
If I (during debug) remove the "__type:..." parameter, it works.
Reading this article I noticed that the problem was not on the webmetho response, but on my deserialization. I shouldn't try to do that.
Because I have some old code there, I will have to find an workaround, maybe storing the values in the hdnField and building the objects in my server side.
Best way is to do unit testing.
Please give the string "data: JSON.stringify({ contacts: _contacts })"
and also the structure of the your ContactInfo object. If possible sniff the request in Chrome Developer Tool, or Firebug, and give the complete HTTP post request. Then we can find the solution immediately.
What happens is, that your ContactInfo has a _Type field, that can't be null, and your provided data (via jQuery/JSON/AJAX/...) does not have a _Type field.
So either you have to adapt your ContactInfo or your JSON Data, could be as easy as
function AddTypeToContacts(contacts) {
var mangledcontacts=new Array();
for (var i=0;i<contacts.Length;i++) {
var c=contacts[i];
if (!c._Type) c._Type='whatever';
mangledcontacts[mangledcontacts.Length]=c;
}
return mangledcontacts;
}
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ contacts: AddTypeToContacts(contacts) }),
dataType: 'json',
url: '/MyPage.aspx/MyMethod',
success: function (result) {
hdn.val(result.d);
}
});

Categories

Resources