Deserialize javascript objects to generic list in c# handler - c#

Im creating some javascript items in a loop
var licenseList = {};
$($licenses).each(function (index) {
var license = {};
var editedValues = {};
license.PRODUCT_KEY = $(this).parent('div.licensewrapper').data('productkey');
$(this).find('input:text').each(function (i, val) {
if ($(val).attr('data-default-value') != $(val).val() && $(val).val() > 0 && $(val).data('isValid') != false) {
var pogKey = $(val).data('product_option_group_key');
var editedValue = $(val).val();
editedValues[pogKey] = editedValue;
license.editedValues = editedValues;
}
});
//licenseList[index] = license;
//liceneList.push(license); //if array...
});
I've commented out my current solutions. But i dont think any of the two are equal to a generic list when derelializing them in c#. Whats the corrent way to do it in this case? Thanks

create your array
var licenseList = [];
for each of your licenses...
var license = {
prop1: 'p1',
prop2: 'p2'
};
licenseList.push(license);
format and serialize JSON data to be sent over to webmethod
data = {
LicenseList: licenseList
};
$.ajax({
...
data: JSON.stringify(data)
...
});
in your webmethod your method parameter must match
[WebMethod]
public static string GetLicenses(List<License> LicenseList)
{
foreach(var license in LicenseList)
{
// do whatever
}
}
sample license class. Your properties need to match with your objects in your javascript
public class License
{
public string Prop1 {get; set;}
public string Prop2 {get; set;}
}
Hope this helps.

function sendToServer(licenseList)
{
var url = "controller.ashx";
var data = {};
data.SerializedObj = JSON.stringify(licenseList);
$.post(url, data, function(response){
if(response.length > 0)
{
alert(response);
}
});
}
//controller.ashx :
public void ProcessRequest (HttpContext context) {
//...
string serializedObj = context.Request.Form["SerializedObj"] ?? "";
JavaScriptSerializer js = new JavaScriptSerializer();
List<license> collection = js.Deserialize<List<license>>(serializedObj);
//...
public class license
{
public string Propertie1 {get;set;}
public string Propertie2 {get;set;}
}
Javascript object must have the same properties:
var license = {Propertie1 : 'value1', Propertie2 : 'value2'};

Related

NewtonSoft json parsing

Can somebody help me to parse the json and get the details.
Lets say i have Top2 input parameter as Police and i want to know the respective Top3 and in that Top3 array i need to check whether Test1Child value is there or not.
I am using newtonsoft json + c# and so far i can get till DeviceTypes using below code
var json = File.ReadAllText(jsonFile); // below json is stored in file jsonFile
var jObject = JObject.Parse(json);
JArray MappingArray =(JArray)jObject["Top1"];
string strTop1 = ObjZone.Top1.ToString();
string strTop2 = ObjZone.Top2.ToString();
var JToken = MappingArray.Where(obj => obj["Top2"].Value<string>() == strTop2).ToList();
//Json
{
"Top1": [
{
"Top2": "Test1",
"Top3": [
"Test1Child"
]
},
{
"Top2": "Test2",
"Top3": [
"Test2Child"
]
}
]
}
I'd use http://json2csharp.com/ (or any other json to c# parser) and then use C# objects (it's just easier for me)
This would look like that for this case:
namespace jsonTests
{
public class DeviceTypeWithResponseTypeMapper
{
public string DeviceType { get; set; }
public List<string> ResponseTypes { get; set; }
}
public class RootObject
{
public List<DeviceTypeWithResponseTypeMapper> DeviceTypeWithResponseTypeMapper { get; set; }
}
}
and the use it like that in code:
var rootob = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(str);
var thoseThatHaveNotUsed = rootob.DeviceTypeWithResponseTypeMapper.Where(dtwrtm =>
dtwrtm.ResponseTypes.Any(rt => rt == "NotUsed"));
foreach (var one in thoseThatHaveNotUsed)
{
Console.WriteLine(one.DeviceType);
}
this code lists all the Device types that have "NotUsed" among the responses.
version 2 (extending your code) would look like that, i believe:
static void Main(string[] args)
{
var json = str; // below json is stored in file jsonFile
var jObject = JObject.Parse(json);
JArray ZoneMappingArray = (JArray)jObject["DeviceTypeWithResponseTypeMapper"];
string strDeviceType = "Police";
string strResponseType = "NotUsed";
var JToken = ZoneMappingArray.Where(obj => obj["DeviceType"].Value<string>() == strDeviceType).ToList();
var isrespTypeThere = JToken[0].Last().Values().Any(x => x.Value<string>() == strResponseType);
Console.WriteLine($"Does {strDeviceType} have response type with value {strResponseType}? {yesorno(isrespTypeThere)}");
}
private static object yesorno(bool isrespTypeThere)
{
if (isrespTypeThere)
{
return "yes!";
}
else
{
return "no :(";
}
}
result:
and if you'd like to list all devices that have response type equal to wanted you can use this code:
var allWithResponseType = ZoneMappingArray.Where(jt => jt.Last().Values().Any(x => x.Value<string>() == strResponseType));
foreach (var item in allWithResponseType)
{
Console.WriteLine(item["DeviceType"].Value<string>());
}

When using jqgrid in asp.net-mvc site, is there a way to include the filter in the url so you can share filtered views?

I have an asp.net-mvc site and I user jqgrid on the front end. I have a simple page using jqgrid and I filter down my jqgrid results (server side filter) using the top bar filter of the advanced filter.
I now want a way where I can share a URL with someone else and when they load the page, they get the same filter applied so somehow I need to take the filter criteria and append it to the query string.
The issue is that I can do this "manually" field by field like this by creating queryparams like
myurl?NameFilter=JoeBrown
and then doing something like this in my asp.net-mvc view
var myfilter = { groupOp: "AND", rules: [] };
<% if (!String.IsNullOrEmpty(Model.NameFilter)) { %>
myfilter.rules.push({ field: "Name", op: "eq", data: "<% = Model.NameFilter%>" });
<%}%>
but that doesn't really scale very well given I have many different pages with lots of columns so I am looking for a more generic way to persist the filter values into a URL and then apply them again so that I can then model bind on the server side back to my controller action.
Here is an example Server Side controller action that I am calling to load data from the server:
public ActionResult GridData(GridData args)
{
var data = GetData(args).Paginate(args.page ?? 1, args.rows ?? 10,
i =>
new
{
i.Id,
i.Name
}
}
so basically I need the query string to bind to my GridData class similar to what happens when I do a normal filter that gets posted on the ajax call when I do a regular filter.
My GridData class looks like this:
public class GridData
{
public int? page { get; set; }
public int? rows { get; set; }
public bool search { get; set; }
public string sidx { get; set; }
public string sord { get; set; }
public Filter Where { get; set; }
}
public class Filter
{
public string groupOp { get; set; }
public Rule[] rules { get; set; }
}
public class Rule
{
public string field { get; set; }
public string op { get; set; }
public string data { get; set; }
}
If you are looking for a way to construct a model that will bind directly from query string values, you can try the following. The methods buildParamsCustom() and serializeJson() are basically taken from jQuery source and modified for creating a query string which will be supported by the MVC default model binder.
http://api.jquery.com/jquery.param/ has the details about the default jQuery implementation.
I have tested for your scenario. I am able to view the serialized data.
var r20 = /%20/g, rbracket = /\[\]$/;
function buildParamsCustom(prefix, obj, traditional, add) {
var name;
if (jQuery.isArray(obj)) {
// Serialize array item.
jQuery.each(obj, function (i, v) {
if (traditional || rbracket.test(prefix)) {
// Treat each array item as a scalar.
add(prefix, v);
} else {
// Item is non-scalar (array or object), encode its numeric index.
buildParamsCustom(prefix + "[" + (typeof v === "object" ? i : "") + "]", v, traditional, add);
}
});
} else if (!traditional && jQuery.type(obj) === "object") {
// Serialize object item.
for (name in obj) {
buildParamsCustom(prefix + "." + name, obj[name], traditional, add);
}
} else {
// Serialize scalar item.
add(prefix, obj);
}
}
// Serialize an array of form elements or a set of
// key/values into a query string
var serializeJson = function (a, traditional) {
var prefix,
s = [],
add = function (key, value) {
// If value is a function, invoke it and return its value
value = jQuery.isFunction(value) ? value() : (value == null ? "" : value);
s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
};
// Set traditional to true for jQuery <= 1.3.2 behavior.
if (traditional === undefined) {
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
}
// If an array was passed in, assume that it is an array of form elements.
if (jQuery.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) {
// Serialize the form elements
jQuery.each(a, function () {
add(this.name, this.value);
});
} else {
// If traditional, encode the "old" way (the way 1.3.2 or older
// did it), otherwise encode params recursively.
for (prefix in a) {
buildParamsCustom(prefix, a[prefix], traditional, add);
}
}
// Return the resulting serialization
return s.join("&").replace(r20, "+");
};
// Get this data from the grid
var data = { "page": 1, "rows": 10, "search": true, "Where": { "groupop": "AND", "rules": [{ "field": "Name", "op": "EQ", data: "John" }, { "field": "Title", "op": "EQ", data: "Mr" }] } };
var queryString = serializeJson(data);
var url = "someurl" + "?" + decodeURIComponent(queryString);
// Send your GET request here.

Ho to pass a Model Object or a Viewbag to Javascript?

I am using asp.net mvc4 with C#. I get the details from Getdeatils() method of student class. This method return an array. Getdetails method also have same fields like studentBO. In the controller I have a method like follows
public ActionResult Index()
{
List<studentBO> list = new List<studentBO>();
Student.GetDetails[] dt = Student.Getdeatils();
for (int i = 0; i < dt.Length; i++)
{
studentBO.name= dt[i].name;
studentBO.studentno= dt[i].studentno;
studentBO.address= dt[i].address;
list1.Add(studentBO);
}
ViewBag.Registrationlist = list1;
return View(list1);
}
studentBO object have 3 fields
public class studentBO
{
public long studentno{ get; set; }
public string name{ get; set; }
public string address{ get; set; }
}
How can I get viewbag or model in my Jquery `$(document).ready(function () {}` function. I want to get every students name. So I have to use foreach loop as well.
You can serialise your item in the ViewBag and write it to the view, so that the Javascript code will be able to read it:
$(document).ready(function() {
var registrationList = #(Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(ViewBag.Registrationlist)));
for (var i = 0; i < registrationList.length; i++) {
var studentno = registrationList[i].studentno;
var name= registrationList[i].name;
var address= registrationList[i].address;
// write some more code to make use of the values
}
});
Use WebAPI to create a service that returns your objects. Then you can use an ajax-call in your Javascript code to fetch the objects.
WebAPI:
public class StudentsController : ApiController
{
IEnumerable<Student.GetDetails> GetDetails()
{
List<studentBO> list = new List<studentBO>();
Student.GetDetails[] dt = Student.Getdeatils();
for (int i = 0; i < dt.Length; i++)
{
studentBO.name= dt[i].name;
studentBO.studentno= dt[i].studentno;
studentBO.address= dt[i].address;
list1.Add(studentBO);
}
return list1;
}
}
Javascript:
$(document).ready(function () {
// Send an AJAX request
$.getJSON("api/students")
.done(function (data) {
// On success, 'data' contains a list of students.
$.each(data, function (key, item) {
//Do something with the student object
});
});
});

AngularJS object is not properly converted into a ViewModel .NET

I have an AngularJS directive which returns me an array with some values, like this below:
The AngularJS code I'm using to generate this object like above is:
//--------------------------
// service...
service.getSelectedOptions = function() {
var options = [];
for (var I = 0; I < service.optionList.length; ++I) {
var availableOption = service.optionList[I];
if (availableOption.selecionado !== '') {
options.push(availableOption);
}
}
return opcoes;
};
//--------------------------
// controller...
var options = [];
var list = OptionsService.getSelectedOptions();
for (var I = 0; I < list.length; ++I) {
var option = list[I];
options.push({ Handle: option.Handle, Selecionado: option.Selecionado });
}
console.log(options);
// Sending the values to backend...
doPost('..../SaveOptions', { options: options }, function (result) { });
Ok, I created a ViewModel class to receive those objects into my controller.
public class OptionsViewModel {
public int Handle { get; set; }
public string Selecionado { get; set; }
}
My controller is declared like this below:
public JsonResult SaveOptions(OptionsViewModel[] options) {
//...
}
The problem is: if I chose 4 options, the array in the backend has 4 options, but the values are not binded to the objects.
Why that? Anyone knows why? Thanks!!
The solution was modify two parameters in the AJAX call:
Set contentType: "application/json";
Use JSON.stringify(parameters) to the parameters.
Thanks!

Adding custom objects to list<object>

I have a problem, I cannot add custom objects to my List. However, if I add some predefined objects (strings, integers..) my code works just fine.
This is my class which is always returned on all ajax calls to this controller, it contains boolean Status and List of objects.
public class returnData
{
public bool status { get; set; }
public List<object> data { get; set; }
}
This is the class for the object I want to add to this list:
public class file
{
public string ID { get; set; }
public string Name { get; set; }
public string Type { get; set; }
}
The code where I use this:
returnData data = new returnData();
...
DriveFile file = JsonConvert.DeserializeObject<DriveFile>(Json);
file f = new file();
if (file.mimeType == "application/vnd.google-apps.folder")
{
f.Type = "folder";
f.ID = file.id;
f.Name = file.title;
data.data.Add(f);
}
The error I get has no useful info, as this code compiles and the error is in Chrome Console log when the ajax is executed.
Image of google chrome console
However, when I use this line of code
data.data.add("some string");
my function will work flawlessly and return Object which contains boolean Status and List of objects (strings, integers..)
So back to my question, how do I add my objects to this list?
EDIT: There are no server side errors, the code compiles and runs just fine, so this probably is some jquery/ajax error.
This is the ajax code for my debugger:
86 $.ajax({
87 url: $('#url').val(),
88 type: $('#type option:selected').val(),
89 contentType: "application/json; charset=utf-8",
90 dataType: "json",
91 data: $('#data').val(),
92 success: function (result){
93 console.log(result)
94 },
95 error: function (err){
96 console.log(err)
97 }
98 });
Here is the complete method, but the method seems to be OK, it is the ajax or something to do with jquery I guess.
[OperationContract]
public returnData listChildren(string folderId)
{
returnData data = new returnData();
List<object> myList= new List<object>();
bool status = true;
try
{
string Json = Response("https://www.googleapis.com/drive/v2/files/" + folderId + "/children", "GET");
//get the children list
if (!Json.Contains("error"))
{
DriveChildlist list = JsonConvert.DeserializeObject<DriveChildlist>(Json);
foreach (DriveChildren child in list.items)
{
string uriString = child.childLink;
//get the info for each child in the list
Json = Response(uriString, "GET");
if (!Json.Contains("error"))
{
DriveFile file = JsonConvert.DeserializeObject<DriveFile>(Json);
file f = new file();
if (file.mimeType == "application/vnd.google-apps.folder")
{
f.Type = "folder";
f.ID = file.id;
f.Name = file.title;
data.data.Add(f);
}
else if (file.mimeType == "application/myMimeType")
{
f.Type = "file";
f.ID = file.id;
f.Name = file.title;
data.data.Add(f);
}
}
else
{
status = false;
}
}
}
else
{
status = false;
}
}
catch(Exception)
{
status = false;
}
data.status = status;
if (!status)
{
data.data = null;
//data.data is null if status is false
}
return data;
}
As written your C# code won't work but will compile. It will throw an error when the ajax is called and you may never see the error message (depending on how your system is setup).
Here is correct code (given your snippet)
returnData data = new returnData();
data.data = new List<object>();
// rest of your code.
I have solved this using the Newtonsoft.Json. I have serialized the object using this code:
string jsondata = JsonConvert.SerializeObject(data);
and then I returned the serialized string instead of object. Looks like visual studio development center failed to serialize my object, even after adding [Serializable()] to my class. Any info on that?

Categories

Resources