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)
Related
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>
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); }
I've got a Dictionary<string,string> that's attached to my model. When it reaches the client it's deserialized properly into [{"Text":"bla","Value":"V1"},{"Text":"abc","Value":"V2"}, {"Text":"def","Value":"V3"}].
It's being sent by the statement return View(model); in my controller.
But when I send the same data down via JsonResult with the following:
var jsonResult = Json(myDictionary, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
It comes out like this:
{V1: "{ Value = V1, Text = bla }", V2: "{ Value = V2, Text = abc }", V3: "{ Value = V3, Text = def }"}
Is there a way to fix this in .NET or do I have to parse this and reconstruct it into something useful in javascript?
You could map your Dictionaty<string, string> into a new object, and then return it using Json:
Mapping: (from another question)
var dict = new Dictionary<string, string> { { "Property", "foo" } };
var convertedObject = new ExpandoObject();
var eoColl = (ICollection<KeyValuePair<string, object>>)convertedObject;
foreach (var kvp in dict)
eoColl.Add(kvp);
dynamic eoDynamic = convertedObject;
And then return it by JSON (as you are already doing):
return Json(convertedObject, JsonRequestBehavior.AllowGet);
And receive in your JavaScript like an normal object:
{
V1: "bar",
V2: "foo",
V3: "caa"
}
I have an array of JSON data already stored in a javascript variable as below:
var data = [{"a":153.15,"b":26.15,"c":item1},{"a":148.63,"b":23.45,"c":item2}];
function alertJson(data) {
Android.alertJson(data);
}
Then, I would like to do in java something like this:
#JavascriptInterface
public void alertJson(Array jsonStr) {
JSONArray jsonarray = new JSONArray(jsonStr);
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject jsonobject = jsonarray.getJSONObject(i);
String a = jsonobject.getString("a");
String b = jsonobject.getString("b");
String c = jsonobject.getString("c");
}
}
Now I am getting an error saying Array cannot be resolved to a type at Array jsonStr.
But the problem is jsonStr is undefined or not initialized. I want to get the value(array) of the javascript variable in jsonStr so I can use it in java. How can I achieve this?
By the way, I know how to bind javascript to android. I guess I just need a way to store the array in jsonStr somehow like using a function. Please help me.
try this
var data = JSON.parse('[{"a":153.15,"b":26.15,"c":item1},{"a":148.63,"b":23.45,"c":item2}]');
and
Android.alertJson(data.stringify());
public void alertJson(Array jsonStr) { // Change Array to String
Had this problem as well. Solution:
var data = [{"a":153.15,"b":26.15,"c":item1},{"a":148.63,"b":23.45,"c":item2}];
var myJSON = JSON.stringify(data );
Android.alertJson(myJSON);
On Android (Kotlin):
#JavascriptInterface
fun alertJson(myJSON: String) {
var jsonarray = JSONArray(myJSON)
// iterate through jsonarray
}
Java (not tested, but probably works)
#JavascriptInterface
public void alertJson(String myJSON) {
JSONArray jsonarray = new JSONArray(myJSON);
// iterate through jsonarray
}
I created a dashboard with widgets awhile ago and I'm now revisiting how to persist the the widgets per user to the database. I thought I was on the right track, but I'm very new to JSON and I'm unable to accomplish what I need. I've researched this and tried multiple things but nothing has worked out so far. Here is my code..
javascript that creates item for update
function updateWidgetData() {
var items = [];
$('.column').each(function () {
var columnId = $(this).attr('id');
$('.dragbox', this).each(function (i) {
var collapsed = 0;
if ($(this).find('.dragbox-content').css('display') == "none")
collapsed = 1;
//Create Item object for current panel
var item = {
id: $(this).attr('id'),
collapsed: collapsed,
order: i,
column: columnId
};
//Push item object into items array
items.push(item);
});
});
//Assign items array to sortorder JSON variable
var sortorder = { items: items };
Now my goal is to pass the sortorder to be saved to the database... but I have this for testing..
var testData = '{ "Column1": "test1", "Column2": "test2"}'
$.ajax ({
url: "/Handlers/SaveWidgets.ashx",
type: "POST",
contentType: "application/json; charset=uft-8",
dataType: "json",
data: testData,
success: function (response) {
alert("Passed json");
},
error: function (error) {
alert("Failed passing json.");
}
});
Then in my handler..
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
string column1 = (string)context.Request.Form["Column1"];
string column2 = (string)context.Request.Form["Column2"];
using (SqlConnection connCao = new SqlConnection(ConfigurationManager.ConnectionStrings["dboCao"].ConnectionString))
{
using(SqlCommand cmdWidget = new SqlCommand("INSERT INTO TestTable (Column1, Column2) VALUES (#column1, #column2)", connCao))
{
cmdWidget.Parameters.AddWithValue("#column1", column1);
cmdWidget.Parameters.AddWithValue("#column2", column2);
connCao.Open();
cmdWidget.ExecuteNonQuery();
connCao.Close();
}
}
}
but I'm getting that it's expecting parameters #column1, and #column2 which were never supplied. So clearly I'm missing how to do something and I'm unable to find what I'm missing on the google machine.
I have used this link here but this doesn't explain the greatest and a few things confused me.
I also found other links but nothing that explains what I'm trying to accomplish. Any help is greatly appreciated!
I would start by creating a class to represent the data you are posting to the handler.
using System;
using System.Runtime.Serialization;
[DataContract]
public class YourDataModel
{
public YourDataModel() { }
// When a property in your model doesn't
// match up exactly you can manually
// specify the name
[DataMember(Name = "Column1")]
public String Col1 { get; set; }
// If things match up exactly (including case)
// you don't need to manually map the Name
[DataMember]
public String Column2 { get; set; }
}
Then modify your handler to create an instance of that class from posted JSON data.
using System;
using System.IO;
using System.Web;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public class SaveWidgets : IHttpHandler {
public void ProcessRequest (HttpContext context)
{
String json = String.Empty;
// you have sent JSON to the server
// read it into a string via the input stream
using (StreamReader rd = new StreamReader(context.Request.InputStream))
{
json = rd.ReadToEnd();
}
// create an instance of YourDataModel from the
// json sent to this handler
YourDataModel data = null;
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(YourDataModel));
using (MemoryStream ms = new MemoryStream())
{
byte[] utf8Bytes = Encoding.UTF8.GetBytes(json);
ms.Write(utf8Bytes, 0, utf8Bytes.Length);
ms.Position = 0;
data = serializer.ReadObject(ms) as YourDataModel;
}
// update the DB and
// send back a JSON response
int rowsUpdated = 0;
using (SqlConnection c = new SqlConnection(ConfigurationManager.ConnectionStrings["dboCao"].ConnectionString))
{
c.Open();
String sql = #"
INSERT INTO TestTable
(Column1, Column2)
VALUES
(#column1, #column2);";
using (SqlCommand cmd = new SqlCommand(sql, c))
{
cmd.Parameters.Add("#column1", SqlDbType.VarChar, 50).Value = data.Col1;
cmd.Parameters.Add("#column2", SqlDbType.VarChar, 50).Value = data.Column2;
rowsUpdated = cmd.ExecuteNonQuery();
}
}
context.Response.ContentType = "application/json";
context.Response.Write("{ \"rows_updated\": " + rowsUpdated + " }");
}
public bool IsReusable {
get { return false; }
}
}