How to convert C# list object to JavaScript array [duplicate] - javascript

I have a datatable that I'm converting into a List, serializing it and passing it to my view using a viewmodel.
My viewmodel looks like this:
public class AddressModel
{
public string Addresses { get; set; }
}
My controller action looks like the following:
AddressModel lAddressGeocodeModel = new AddressGeocodeModel();
List<string[]> lAddresses = new List<string[]>();
string lSQL = " select Address1, CityName, StateCode, ZipCode " +
" from AddressTable ";
// Convert the data to a List to be serialized into a Javascript array.
//{
...data retrieval code goes here...
//}
foreach (DataRow row in AddressTable.Rows)
{
string[] lAddress = new string[5];
lAddress[1] = row["Address1"].ToString();
lAddress[2] = row["CityName"].ToString();
lAddress[3] = row["StateCode"].ToString();
lAddress[4] = row["ZipCode"].ToString();
lAddresses.Add(lAddress);
}
lAddressGeocodeModel.UnitCount = lAddresses.Count().ToString();
// Here I'm using the Newtonsoft JSON library to serialize my List
lAddressGeocodeModel.Addresses = JsonConvert.SerializeObject(lAddresses);
return View(lAddressModel);
Then in my view I get the following string of addresses:
[["123 Street St.","City","CA","12345"],["456 Street St.","City","UT","12345"],["789 Street St.","City","OR","12345"]]
How am I supposed to get this serialized string residing in a razor model into a javascript array?

You could directly inject the values into JavaScript:
//View.cshtml
<script type="text/javascript">
var arrayOfArrays = JSON.parse('#Html.Raw(Model.Addresses)');
</script>
See JSON.parse, Html.Raw
Alternatively you can get the values via Ajax:
public ActionResult GetValues()
{
// logic
// Edit you don't need to serialize it just return the object
return Json(new { Addresses: lAddressGeocodeModel });
}
<script type="text/javascript">
$(function() {
$.ajax({
type: 'POST',
url: '#Url.Action("GetValues")',
success: function(result) {
// do something with result
}
});
});
</script>
See jQuery.ajax

Many way to Json Parse but i have found most effective way to
#model List<string[]>
<script>
function DataParse() {
var model = '#Html.Raw(Json.Encode(Model))';
var data = JSON.parse(model);
for (i = 0; i < data.length; i++) {
......
}
}
</script>

This worked for me in ASP.NET Core MVC.
<script type="text/javascript">
var ar = #Html.Raw(Json.Serialize(Model.Addresses));
</script>

Many of these answers do work, but I have found the easiest way by far is to send data through ViewData or ViewBag and let JSON.Net serialize it.
I use this technique when Javascript is needed for HTML generation before the page load or when AJAX overhead needs to be avoided:
In the controller:
public ActionResult MyController()
{
var addresses = myAddressesGetter();
ViewData["addresses"] = addresses ;
return View();
}
In the view:
#section scripts {
<script type="text/javascript">
var MyjavascriptAddresses: #Html.Raw(JsonConvert.SerializeObject(ViewData["addresses"])),
</script>
}
You can always rely on JSON.NET whereas some browsers have poor JSON deserialization support.
Another benefit over some methods in that you can see the Javascript using your browser's View --> Source, since it is simply text generated server-side.
Note that In most situations, Web API a more elegant way to get JSON to the client.

For those trying to do it without using JSON, the following is how I did it:
<script>
var originalLabels = [ '#Html.Raw(string.Join("', '", Model.labels))'];
</script>

I would say it's more a problem of the way you're modeling your data. Instead of using string arrays for addresses, it would be much cleaner and easier to do something like this:
Create a class to represent your addresses, like this:
public class Address
{
public string Address1 { get; set; }
public string CityName { get; set; }
public string StateCode { get; set; }
public string ZipCode { get; set; }
}
Then in your view model, you can populate those addresses like this:
public class ViewModel
{
public IList<Address> Addresses = new List<Address>();
public void PopulateAddresses()
{
foreach(DataRow row in AddressTable.Rows)
{
Address address = new Address
{
Address1 = row["Address1"].ToString(),
CityName = row["CityName"].ToString(),
StateCode = row["StateCode"].ToString(),
ZipCode = row["ZipCode"].ToString()
};
Addresses.Add(address);
}
lAddressGeocodeModel.Addresses = JsonConvert.SerializeObject(Addresses);
}
}
Which will give you JSON that looks like this:
[{"Address1" : "123 Easy Street", "CityName": "New York", "StateCode": "NY", "ZipCode": "12345"}]

Here's how you accomplish that:
//View.cshtml
<script type="text/javascript">
var arrayOfArrays = JSON.parse('#Html.Raw(Json.Encode(Model.Addresses))');
</script>

For one dimension array
Controller:
using Newtonsoft.Json;
var listOfIds = _dbContext.Countries.Where(x => x.Id == Country.USA).First().Cities.Where(x => x.IsCoveredByCompany).Select(x => x.Id).ToList();
string strArrayForJS = JsonConvert.SerializeObject(listOfIds); // [1,2,6,7,8,18,25,61,129]
//Now pass it to the view through the model or ViewBag
View:
<script>
$(function () {
var myArray = #HTML.Raw(Model.strArrayForJS);
console.log(myArray); // [1, 2, 6, 7, 8, 18, 25, 61, 129]
console.log(typeof (myArray)); //object
});
</script>

JSON is valid JavaScript Object anyway, while you are printing JavaScript itself, you don't need to encode/decode JSON further once it is converted to JSON.
<script type="text/javascript">
var addresses = #Html.Raw(Model.Addresses);
</script>
Following will be printed, and it is valid JavaScript Expression.
<script type="text/javascript">
var addresses = [["123 Street St.","City","CA","12345"],["456 Street St.","City","UT","12345"],["789 Street St.","City","OR","12345"]];
</script>

You can directly use the Json.Serialize of the C#
<script type="text/javascript">
var addresses = #Json.Serialize(Model.Addresses);
</script>

Related

ASP.NET MVC Passing a BeginCollectionItem List's Object through AJAX with Javascript Serialize to Controller is passing null

This has been giving me some trouble for the past few days. I'm going to try to be as detailed as possible with what I want and the issue I'm having. I tried to simplify my controllers, models, etc as much as I can for the sake of the question.
Here's the flow of sequences I'm trying to get to work.
Give user a view with inputs for List<MyObject> in the main ViewModel
User can hit a button to add another row to add another object to that List of objects to post later
Hitting the button POSTs the object (in same container) through AJAX from the currently displayed list in order to repeat most of the inputs for the new row (MyObject)
Controller takes passed MyObject and maps some of the prior values to the new object
Controller passes back new MyObject and ajax appends the result html to my table
The Problem
The Ajax is passing the on-page MyObject as null (or C# doesn't know how to interpret) to my controller (step 4 above). I can't seem to get the object passed to the controller through the Ajax call.
What I've got
Models:
public class MyViewModel
{
// irrelevant properties
public List<MyObject> MyObjects { get; set; } = new List<MyObject>();
}
public class MyObject
{
public int Id { get; set; }
public string Name { get; set; }
public string AnotherProperty { get; set; }
public decimal AdditionalProperty { get; set; }
public List<MySubObject> MySubObjects { get; set; } = new List<MySubObject>();
}
public class MySubObject
{
public bool IsChecked { get; set; }
public bool Name { get; set; }
}
Controller GET:
public ActionResult Edit(int? id)
{
var viewModel = new MyViewModel();
// for list of checkboxes
var subObjects = new List<MySubObject>();
// get subobjects from db
subObjects.Add(new MySubObject {
Name = "SubObj1", IsChecked = false
});
subObjects.Add(new MySubObject {
Name = "SubObj12",
IsChecked = false
});
// populate viewModel with a blank MyObject
viewModel.MyObjects.Add(new MyObject
{
MySubObjects = subObjects
});
return (viewModel);
}
View (and AJAX call):
<table id="myObjectInputs">
#foreach (var obj in Model.MyObjects)
{
#Html.Partial("~/Areas/Admin/Views/Shared/EditorTemplates/MyObject.cshtml", obj)
}
</table>
<script>
$(document).ready(function () {
$("#myObjectInputs").on("focus", ".make-new-row", function () {
var plusButton = $(this);
var currentArea = plusButton.closest(".myobject-container");
var serializedData = currentArea.find(":input").serialize();
// add new row
$.ajax({
url: this.href,
cache: false,
type: "POST",
data: { "myObject": serializedData },
success: function (html) { $("#myObjectInputs").append(html); }
});
return false;
});
});
</script>
EditorTemplates/MyObject.cshtml:
#using HtmlHelpers.BeginCollectionItem
#model LD.Areas.Admin.Models.MyObject
<tbody class="myobject-container" style="border:solid 1px red;">
#using (Html.BeginCollectionItem("MyObjects"))
{
<tr>
<td>#Html.HiddenFor(x => x.Id)</td>
<td>#Html.EditorFor(x => x.Name)</td>
<td>#Html.EditorFor(x => x.AnotherProperty)</td>
<td>#Html.EditorFor(x => x.AdditionalProperty)</td>
<td>
#foreach (var subObj in Model.MySubObjects)
{
#Html.Partial("~/Areas/Admin/Views/Shared/EditorTemplates/MySubObject.cshtml", subObj)
}
</td>
<td>
<!-- the button that calls the function / AJAX -->
#Html.ActionLink("+", "NewMyObjectSection", null, new { #class = "make-new-row" })
</td>
</tr>
}
</tbody>
EditorTemplates/MySubObject.cshtml
#using HtmlHelpers.BeginCollectionItem
#model LD.Areas.Admin.Models.MySubObject
#using (Html.BeginCollectionItem("MySubObjects"))
{
<label>
#Html.HiddenFor(x => x.Id)
#Html.HiddenFor(x => x.Name)
#Html.EditorFor(x => x.IsChecked)#Html.LabelFor(x => x.IsChecked, Model.Name)
<text> </text>
</label>
}
ActionResult called by AJAX: (this is I'm getting null for MyObject)
public ActionResult NewMyObjectSection(MyObject myObject)
{
// take passed object values and create a new object based on myObject
var newObject = new MyObject();
return PartialView("~/Areas/Admin/Views/Shared/EditorTemplates/MyObject.cshtml", myObject);
}
What I've Tried
Some main things that stick out to me are that BeginCollectionItem attaches a GUID to make the collection items unique, for ex, when my <tablebody class="myobject-container"> is serialized, it looks like this (this is the result from my real object, Rates == MyObjects):
"Rates.index=b589808e-3e99-40f2-827c-58feaa9bebc3&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.OrganismNid=0&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.OrganismName=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.OrganismUpdateType=New&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.IsPest=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.IsPreEmergent=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.IsPostEmergent=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.IsSafeOn=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.HasControl=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.HasSuppression=false&ControlTypes.index=bd9d1180-9768-4ca4-8316-fc5cbf62ca97&ControlTypes%5Bbd9d1180-9768-4ca4-8316-fc5cbf62ca97%5D.ControlTypeNid=1&ControlTypes%5Bbd9d1180-9768-4ca4-8316-fc5cbf62ca97%5D.Name=Annual&ControlTypes%5Bbd9d1180-9768-4ca4-8316-fc5cbf62ca97%5D.IsChecked=false&ControlTypes.index=0264b842-5cac-4b1a-8b79-8f9a13a26428&ControlTypes%5B0264b842-5cac-4b1a-8b79-8f9a13a26428%5D.ControlTypeNid=2&ControlTypes%5B0264b842-5cac-4b1a-8b79-8f9a13a26428%5D.Name=Biennial&ControlTypes%5B0264b842-5cac-4b1a-8b79-8f9a13a26428%5D.IsChecked=false&ControlTypes.index=6a344551-add6-4e9b-96e2-59a6fc857327&ControlTypes%5B6a344551-add6-4e9b-96e2-59a6fc857327%5D.ControlTypeNid=3&ControlTypes%5B6a344551-add6-4e9b-96e2-59a6fc857327%5D.Name=Winter%20Annual&ControlTypes%5B6a344551-add6-4e9b-96e2-59a6fc857327%5D.IsChecked=false&ControlTypes.index=91f5c6ff-402e-48ae-8f9c-1131511699a8&ControlTypes%5B91f5c6ff-402e-48ae-8f9c-1131511699a8%5D.ControlTypeNid=4&ControlTypes%5B91f5c6ff-402e-48ae-8f9c-1131511699a8%5D.Name=Perennial&ControlTypes%5B91f5c6ff-402e-48ae-8f9c-1131511699a8%5D.IsChecked=false&ControlTypes.index=3248ec07-09a8-4bf0-b99f-a518807d9636&ControlTypes%5B3248ec07-09a8-4bf0-b99f-a518807d9636%5D.ControlTypeNid=5&ControlTypes%5B3248ec07-09a8-4bf0-b99f-a518807d9636%5D.Name=Top%20Growth%20Control%20Only&ControlTypes%5B3248ec07-09a8-4bf0-b99f-a518807d9636%5D.IsChecked=false&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.BroadcastMin=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.BroadcastMax=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.BroadcastChemUnitTypeNid=1&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.BroadcastAreaUnitTypeNid=9&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.SpotMin=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.SpotMax=&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.SpotChemUnitTypeNid=1&Rates%5Bb589808e-3e99-40f2-827c-58feaa9bebc3%5D.SpotFinalSolutionUnitTypeNid=1"
I'm not sure if my controller understands to bind that to my object.
I've tried other methods of passing it, such as stripping out GUIDs and extra junk from the string, passing it as a string and deserializing in C#, and others:
var serializedArray = currentArea.find(":input").serializeArray();
//https://www.regextester.com/94410
var regex = new RegExp("(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}");
var stripped = serializedData.replace(/(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}/g, '');
stripped = stripped.replace(/%5B/g, '[').replace(/%5D/g, ']');
var strung = JSON.stringify({ "modelData": serializedData });
At this point I'm at a loss. This is for a personal passion project and my lack of AJAX / JSON knowledge is really holding me back. I'm not sure what else to try. Any pointing in the right direction would be appreciated.
public ActionResult NewMyObjectSection([FromBody] MyObject myObject)
{
//myObject should be correctly populated from the request
return PartialView("~/Areas/Admin/Views/Shared/EditorTemplates/MyObject.cshtml", myObject);
}
Id Expect the item to come as a Json Object correctly passed in your request to that your myObject is populated automatically
for the request part:
var dat = {
Id:3,
Name:7,
AnotherProperty:"",
AdditionalProperty:"",
MySubObjects:[
//Create sub objects here
]
};
$.ajax({
type: "POST",
url: "youraction",
data: JSON.stringify(dat),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){alert(data);},
failure: function(errMsg) {
alert(errMsg);
}
});
})

Print model data without saving

if (saleDetails.length) {
var htmlData;
var paymentStatus = 0;
if ($('#PaymentStatus option:selected').val() != 0) {
paymentStatus = $('#PaymentStatus option:selected').text()
}
var SaleAmount = parseFloat(total + vat).toFixed(2);
var data = {
'AccountID': $('#hdnAccountID').val(),
'QuoteID': $('#hdnQuoteID').val(),
'BranchID': $('#BranchID option:selected').val(),
'PONO': $('#PONO').val(),
'PaymentStatus': $('#PaymentStatus').val(),
'SalesDate': $('#SaleDate').val(),
'PaymentStatus': paymentStatus,
'PaymentTypeID': $('#PaymentType option:selected').val(),
'VAT': vat,
'TotalAmount': invoiceAmount,
'DiscountAmount': $('#discInput').val(),
'AmountPaid': $('#amountPaid').val(),
'SaleDetails': saleDetails
};
var json = JSON.stringify({ 'model': data });
public ActionResult printOrder(Models.DTO.Sales model)
{
return PartialView(model);
//return View(model);
}
I am working on POS , In sales client requirement is that we should give him an option of print , so that if client click on Print button we should open a new tab and show invoice , so client can take out print and if customer pay him then client will save SalesOrder.
The problem I am facing is that I am unable to open new tab from controller . And if I am trying to do this from java script I am unable to pass model to view from java script.
So please help me in this issue as I am not too much expert in MVC.
You can use Html.ActionLink to open the page in new tab from your Razor page as below.
#Html.ActionLink("Print", "Action", new { controller="PrintOrder" }, new { target="_blank" })
Html.ActionLink however does not allow you to pass complex objects. You can use trick as mentioned in this stackoverflow answer to pass your model. From the post:
MODEL: Make static Serialize and Deserialize methods in the class like
public class XYZ {
// Some Fields
public string X { get; set; }
public string Y { get; set; }
public string X { get; set; }
// This will convert the passed XYZ object to JSON string
public static string Serialize(XYZ xyz)
{
var serializer = new JavaScriptSerializer();
return serializer.Serialize(xyz);
}
// This will convert the passed JSON string back to XYZ object
public static XYZ Deserialize(string data)
{
var serializer = new JavaScriptSerializer();
return serializer.Deserialize<XYZ>(data);
}
}
VIEW: Now convert your complex object to JSON string before passing it in
Action View <%= Html.ActionLink(Model.x, "SomeAction", new { modelString = XYZ.Serialize(Model) })%>
CONTROLLER: Get the
object as string in Action method and convert it back to object before
using public ActionResult SomeAction(string modelString) { XYX xyz = XYX.Deserialize(modelString); }

How to pass a list of string to a javascript using Razor on ASP.NET MVC? [duplicate]

I have a datatable that I'm converting into a List, serializing it and passing it to my view using a viewmodel.
My viewmodel looks like this:
public class AddressModel
{
public string Addresses { get; set; }
}
My controller action looks like the following:
AddressModel lAddressGeocodeModel = new AddressGeocodeModel();
List<string[]> lAddresses = new List<string[]>();
string lSQL = " select Address1, CityName, StateCode, ZipCode " +
" from AddressTable ";
// Convert the data to a List to be serialized into a Javascript array.
//{
...data retrieval code goes here...
//}
foreach (DataRow row in AddressTable.Rows)
{
string[] lAddress = new string[5];
lAddress[1] = row["Address1"].ToString();
lAddress[2] = row["CityName"].ToString();
lAddress[3] = row["StateCode"].ToString();
lAddress[4] = row["ZipCode"].ToString();
lAddresses.Add(lAddress);
}
lAddressGeocodeModel.UnitCount = lAddresses.Count().ToString();
// Here I'm using the Newtonsoft JSON library to serialize my List
lAddressGeocodeModel.Addresses = JsonConvert.SerializeObject(lAddresses);
return View(lAddressModel);
Then in my view I get the following string of addresses:
[["123 Street St.","City","CA","12345"],["456 Street St.","City","UT","12345"],["789 Street St.","City","OR","12345"]]
How am I supposed to get this serialized string residing in a razor model into a javascript array?
You could directly inject the values into JavaScript:
//View.cshtml
<script type="text/javascript">
var arrayOfArrays = JSON.parse('#Html.Raw(Model.Addresses)');
</script>
See JSON.parse, Html.Raw
Alternatively you can get the values via Ajax:
public ActionResult GetValues()
{
// logic
// Edit you don't need to serialize it just return the object
return Json(new { Addresses: lAddressGeocodeModel });
}
<script type="text/javascript">
$(function() {
$.ajax({
type: 'POST',
url: '#Url.Action("GetValues")',
success: function(result) {
// do something with result
}
});
});
</script>
See jQuery.ajax
Many way to Json Parse but i have found most effective way to
#model List<string[]>
<script>
function DataParse() {
var model = '#Html.Raw(Json.Encode(Model))';
var data = JSON.parse(model);
for (i = 0; i < data.length; i++) {
......
}
}
</script>
This worked for me in ASP.NET Core MVC.
<script type="text/javascript">
var ar = #Html.Raw(Json.Serialize(Model.Addresses));
</script>
Many of these answers do work, but I have found the easiest way by far is to send data through ViewData or ViewBag and let JSON.Net serialize it.
I use this technique when Javascript is needed for HTML generation before the page load or when AJAX overhead needs to be avoided:
In the controller:
public ActionResult MyController()
{
var addresses = myAddressesGetter();
ViewData["addresses"] = addresses ;
return View();
}
In the view:
#section scripts {
<script type="text/javascript">
var MyjavascriptAddresses: #Html.Raw(JsonConvert.SerializeObject(ViewData["addresses"])),
</script>
}
You can always rely on JSON.NET whereas some browsers have poor JSON deserialization support.
Another benefit over some methods in that you can see the Javascript using your browser's View --> Source, since it is simply text generated server-side.
Note that In most situations, Web API a more elegant way to get JSON to the client.
For those trying to do it without using JSON, the following is how I did it:
<script>
var originalLabels = [ '#Html.Raw(string.Join("', '", Model.labels))'];
</script>
I would say it's more a problem of the way you're modeling your data. Instead of using string arrays for addresses, it would be much cleaner and easier to do something like this:
Create a class to represent your addresses, like this:
public class Address
{
public string Address1 { get; set; }
public string CityName { get; set; }
public string StateCode { get; set; }
public string ZipCode { get; set; }
}
Then in your view model, you can populate those addresses like this:
public class ViewModel
{
public IList<Address> Addresses = new List<Address>();
public void PopulateAddresses()
{
foreach(DataRow row in AddressTable.Rows)
{
Address address = new Address
{
Address1 = row["Address1"].ToString(),
CityName = row["CityName"].ToString(),
StateCode = row["StateCode"].ToString(),
ZipCode = row["ZipCode"].ToString()
};
Addresses.Add(address);
}
lAddressGeocodeModel.Addresses = JsonConvert.SerializeObject(Addresses);
}
}
Which will give you JSON that looks like this:
[{"Address1" : "123 Easy Street", "CityName": "New York", "StateCode": "NY", "ZipCode": "12345"}]
Here's how you accomplish that:
//View.cshtml
<script type="text/javascript">
var arrayOfArrays = JSON.parse('#Html.Raw(Json.Encode(Model.Addresses))');
</script>
For one dimension array
Controller:
using Newtonsoft.Json;
var listOfIds = _dbContext.Countries.Where(x => x.Id == Country.USA).First().Cities.Where(x => x.IsCoveredByCompany).Select(x => x.Id).ToList();
string strArrayForJS = JsonConvert.SerializeObject(listOfIds); // [1,2,6,7,8,18,25,61,129]
//Now pass it to the view through the model or ViewBag
View:
<script>
$(function () {
var myArray = #HTML.Raw(Model.strArrayForJS);
console.log(myArray); // [1, 2, 6, 7, 8, 18, 25, 61, 129]
console.log(typeof (myArray)); //object
});
</script>
JSON is valid JavaScript Object anyway, while you are printing JavaScript itself, you don't need to encode/decode JSON further once it is converted to JSON.
<script type="text/javascript">
var addresses = #Html.Raw(Model.Addresses);
</script>
Following will be printed, and it is valid JavaScript Expression.
<script type="text/javascript">
var addresses = [["123 Street St.","City","CA","12345"],["456 Street St.","City","UT","12345"],["789 Street St.","City","OR","12345"]];
</script>
You can directly use the Json.Serialize of the C#
<script type="text/javascript">
var addresses = #Json.Serialize(Model.Addresses);
</script>

Create JSON Object Using ASP.NET [duplicate]

I just used the XmlWriter to create some XML to send back in an HTTP response. How would you create a JSON string. I assume you would just use a stringbuilder to build the JSON string and them format your response as JSON?
Using Newtonsoft.Json makes it really easier:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string json = JsonConvert.SerializeObject(product);
Documentation: Serializing and Deserializing JSON
You could use the JavaScriptSerializer class, check this article to build an useful extension method.
Code from article:
namespace ExtensionMethods
{
public static class JSONHelper
{
public static string ToJSON(this object obj)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(obj);
}
public static string ToJSON(this object obj, int recursionDepth)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RecursionLimit = recursionDepth;
return serializer.Serialize(obj);
}
}
}
Usage:
using ExtensionMethods;
...
List<Person> people = new List<Person>{
new Person{ID = 1, FirstName = "Scott", LastName = "Gurthie"},
new Person{ID = 2, FirstName = "Bill", LastName = "Gates"}
};
string jsonString = people.ToJSON();
Simlpe use of Newtonsoft.Json and Newtonsoft.Json.Linq libraries.
//Create my object
var myData = new
{
Host = #"sftp.myhost.gr",
UserName = "my_username",
Password = "my_password",
SourceDir = "/export/zip/mypath/",
FileName = "my_file.zip"
};
//Tranform it to Json object
string jsonData = JsonConvert.SerializeObject(myData);
//Print the Json object
Console.WriteLine(jsonData);
//Parse the json object
JObject jsonObject = JObject.Parse(jsonData);
//Print the parsed Json object
Console.WriteLine((string)jsonObject["Host"]);
Console.WriteLine((string)jsonObject["UserName"]);
Console.WriteLine((string)jsonObject["Password"]);
Console.WriteLine((string)jsonObject["SourceDir"]);
Console.WriteLine((string)jsonObject["FileName"]);
This library is very good for JSON from C#
http://james.newtonking.com/pages/json-net.aspx
This code snippet uses the DataContractJsonSerializer from System.Runtime.Serialization.Json in .NET 3.5.
public static string ToJson<T>(/* this */ T value, Encoding encoding)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using (var stream = new MemoryStream())
{
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(stream, encoding))
{
serializer.WriteObject(writer, value);
}
return encoding.GetString(stream.ToArray());
}
}
If you need complex result (embedded) create your own structure:
class templateRequest
{
public String[] registration_ids;
public Data data;
public class Data
{
public String message;
public String tickerText;
public String contentTitle;
public Data(String message, String tickerText, string contentTitle)
{
this.message = message;
this.tickerText = tickerText;
this.contentTitle = contentTitle;
}
};
}
and then you can obtain JSON string with calling
List<String> ids = new List<string>() { "id1", "id2" };
templateRequest request = new templeteRequest();
request.registration_ids = ids.ToArray();
request.data = new templateRequest.Data("Your message", "Your ticker", "Your content");
string json = new JavaScriptSerializer().Serialize(request);
The result will be like this:
json = "{\"registration_ids\":[\"id1\",\"id2\"],\"data\":{\"message\":\"Your message\",\"tickerText\":\"Your ticket\",\"contentTitle\":\"Your content\"}}"
Hope it helps!
You can also try my ServiceStack JsonSerializer it's the fastest .NET JSON serializer at the moment. It supports serializing DataContracts, any POCO Type, Interfaces, Late-bound objects including anonymous types, etc.
Basic Example
var customer = new Customer { Name="Joe Bloggs", Age=31 };
var json = JsonSerializer.SerializeToString(customer);
var fromJson = JsonSerializer.DeserializeFromString<Customer>(json);
Note: Only use Microsofts JavaScriptSerializer if performance is not important to you as I've had to leave it out of my benchmarks since its up to 40x-100x slower than the other JSON serializers.
Take a look at http://www.codeplex.com/json/ for the json-net.aspx project. Why re-invent the wheel?
If you want to avoid creating a class and create JSON then Create a dynamic Object and Serialize Object.
dynamic data = new ExpandoObject();
data.name = "kushal";
data.isActive = true;
// convert to JSON
string json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
Read the JSON and deserialize like this:
// convert back to Object
dynamic output = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
// read a particular value:
output.name.Value
ExpandoObject is from System.Dynamic namespace.
If you can't or don't want to use the two built-in JSON serializers (JavaScriptSerializer and DataContractJsonSerializer) you can try the JsonExSerializer library - I use it in a number of projects and works quite well.
If you're trying to create a web service to serve data over JSON to a web page, consider using the ASP.NET Ajax toolkit:
http://www.asp.net/learn/ajax/tutorial-05-cs.aspx
It will automatically convert your objects served over a webservice to json, and create the proxy class that you can use to connect to it.
Encode Usage
Simple object to JSON Array EncodeJsObjectArray()
public class dummyObject
{
public string fake { get; set; }
public int id { get; set; }
public dummyObject()
{
fake = "dummy";
id = 5;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append('[');
sb.Append(id);
sb.Append(',');
sb.Append(JSONEncoders.EncodeJsString(fake));
sb.Append(']');
return sb.ToString();
}
}
dummyObject[] dummys = new dummyObject[2];
dummys[0] = new dummyObject();
dummys[1] = new dummyObject();
dummys[0].fake = "mike";
dummys[0].id = 29;
string result = JSONEncoders.EncodeJsObjectArray(dummys);
Result:
[[29,"mike"],[5,"dummy"]]
Pretty Usage
Pretty print JSON Array PrettyPrintJson() string extension method
string input = "[14,4,[14,\"data\"],[[5,\"10.186.122.15\"],[6,\"10.186.122.16\"]]]";
string result = input.PrettyPrintJson();
Results is:
[
14,
4,
[
14,
"data"
],
[
[
5,
"10.186.122.15"
],
[
6,
"10.186.122.16"
]
]
]
The DataContractJSONSerializer will do everything for you with the same easy as the XMLSerializer. Its trivial to use this in a web app. If you are using WCF, you can specify its use with an attribute. The DataContractSerializer family is also very fast.
I've found that you don't need the serializer at all. If you return the object as a List.
Let me use an example.
In our asmx we get the data using the variable we passed along
// return data
[WebMethod(CacheDuration = 180)]
public List<latlon> GetData(int id)
{
var data = from p in db.property
where p.id == id
select new latlon
{
lat = p.lat,
lon = p.lon
};
return data.ToList();
}
public class latlon
{
public string lat { get; set; }
public string lon { get; set; }
}
Then using jquery we access the service, passing along that variable.
// get latlon
function getlatlon(propertyid) {
var mydata;
$.ajax({
url: "getData.asmx/GetLatLon",
type: "POST",
data: "{'id': '" + propertyid + "'}",
async: false,
contentType: "application/json;",
dataType: "json",
success: function (data, textStatus, jqXHR) { //
mydata = data;
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
console.log(xmlHttpRequest.responseText);
console.log(textStatus);
console.log(errorThrown);
}
});
return mydata;
}
// call the function with your data
latlondata = getlatlon(id);
And we get our response.
{"d":[{"__type":"MapData+latlon","lat":"40.7031420","lon":"-80.6047970}]}
Include:
using System.Text.Json;
Then serialize your object_to_serialize like this:
JsonSerializer.Serialize(object_to_serialize)

MVC controller's string[] parameter is null when posting JSON data

I post data with jQuery but I have a problem with array data. The values supplied to the MVC controller are always null.
This is my JavaScript code:
var FilterCategory = $('input:checkbox:checked').map(function () {
return this.value;
}).get();
var posting = $.post(url, { cursorid: lastid, CatFilter: FilterCategory });
The form data from the network:
cursorid:5434cdc84ba4dd0c40396851
Filter[]:1
Filter[]:3
Filter[]:4
Here's the C# side:
public ActionResult GetDataTweets(string cursorid,string[] CatFilter)
{
bla bla
}
cursorid has a value, but CatFilter is null.
What do I need to do to have the correct value supplied to CatFilter?
This code here:
var posting = $.post(url, { cursorid: lastid, CatFilter: FilterCategory });
From MVC's perspective it's sending a class, so you need a reciprocal C# class to package the data.
Create a class to handle that data, for example:
I am assuming your CatFilter array is a string array:
public class Data{
public string cursorid { get; set;}
public string[] CatFilter {get; set;}
}
Then change your controller:
public ActionResult GetDataTweets(Data data)
{
var s1 = data.cursorid;
var s2 = data.CatFilter[0];
}
if CatFilter is a class then you'd need to create a CatFilter class to map to the javascript version.

Categories