I recently used C# to build a web service client. I chose C# because the web services components are powerful and easy (much easier to work with than Gsoap or Axis IMO).
My C# app runs in the background and should return data that other pieces of my application (which includes a web app, a PLC, and a database) can store and use.
My responses look something like this:
[
[
string
int
[]
]
string
[]
int
]
etc...
The point is that the return values are not simple. My question is what is the best way to reformat and consume this data from other parts of my application?
My choices are:
XML
JSON
I've checked out both routes and have not found a great way to serialize this data. Can anyone provide any recommendations?
Worst case scenario I may need to just create a common routine to build XML with StringBuilder, but I'm hoping there's something I don't know about yet (I'm new to C#) that will make my life easy.
You surelly can use JSON.
Use the JavaScriptSerializer class to serialize the data and your OK: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
var data = new { name = "someValue", id = 1 };
var json = new System.Web.Script.Serialization.JavaScriptSerializer();
return json.Serialize(data);
I haven't tested this code (I'm not in my dev machine by now), but I'm sure it works with some adjustments to your needs.
Why don't you create DTO classes for the return value and use either JSON or XML serialization? It is very convenient.
Related
I have a list of Departments and would like to show them inside a treeview. Im using C#, ASP.NET. I found this cool control called Treed http://bl.ocks.org/mbostock/raw/4339083/dd87a364df6d921740af7e5badef247665918919/ however it requires a JSON file.
What would be the best possible way to achieve this kind of JSON structure from ASP.net?
http://bl.ocks.org/mbostock/raw/4063550/flare.json
Currently I store this data as a DataTable. If there's a solution through any other collection please do advice as Im open to anything at this point.
Many Thanks for your help.
First off, there are a couple of built-in serializers. You can use WCF DataContracts and the DataContractJsonSerializer to produce JSON data designed for consumption by your service endpoints. If your application uses a lot of WCF in its service architecture anyway, this serializer should be easy enough to incorporate.
There is also a JavaScriptSerializer class in System.Web.Script.Serialization; it has a less aspect-oriented customization scheme, requiring you to define a custom converter class if the serializer can't understand your class (or its default behavior isn't what you want), but given you control both the production and consumption of this JSON data and so you can theoretically adapt the client-side scripting to deal with the default behavior, overall this is probably the simplest way to turn an object into JSON.
Lastly, there's a third-party library, JSON.NET, available at http://www.newtonsoft.com/json. It's pretty good; I've used it in a few projects for JSON results of AJAX-y ScriptMethods. It has attributes you can use to make small customizations to serialization behavior, without the full weight of WCF DataContracts.
Have you considered this example:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
string json = JsonConvert.SerializeObject(product);
// {
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Sizes": [
// "Small"
// ]
// }
Here are some links to consider:
This link lets you generate c# classes with JSON:
http://json2csharp.com/
This link supports classes to JSON
http://www.json.net
My Problem is that when I browse to the service URL I see "key-value" pairs but I don't see the name of the array or object, I need the name because I want to use that service for android.
it looks like this:
My code looks like this:
1. In ValueController I have method:
[AcceptVerbs("GET", "POST")]
public List<BuzzMonitor.Web.Message> Search(string text, DateTime dateFrom, DateTime dateTo, [ModelBinder]List<int> themeIds, [ModelBinder]List<int> sourceIds)
{
MessageHandler mh = new MessageHandler();
List<BuzzMonitor.Web.Message> messages = null;
messages = mh.Search(text,dateFrom,dateTo,themeIds,sourceIds);
return messages;
}
2. In Global.asax I added:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
Does anyone have an idea on what is missing when I don't see full JSON, and see just key:value pairs? Thank you for help!
I think you are thinking that you are not seeing the array name or class right? and that is an error?
The answer is NO.
Reason? Well, JSON was invented to share objects easily over network and the main goal was to make it independent of the underlying architecture -
http://www.json.org/
that is why you don't see array names or variable names, only the object notation. Thats JSON stands for Java Script Object Notation. It's the responsibility of the receiving side to re-construct the object from the data provided in json format.
in your case messages is an array with a list of data and so does the output -
[] means array and {} inside that means it has only one object in it.
EDIT: You can also use this to parse json -
http://developer.android.com/reference/org/json/JSONTokener.html
related
Design Strongly typed object from XML
Currently we run stored procedures based on "SQL XML" where in we send xml string as input to stored procedures and get the response from stored procedures as xml. For a simple demonstration of user logging into application here is how it is done
<Request Type="" CRUD="C/R/U/D">`
<Users>
<UserName></UserName>
<Password></Password>
</Users>
</Request>
don't mind about the response from database because that we can change to anything we desired to. It is this construction of xml that we find too intimidating. Below is code we follow
StringBuilder _sbXml = new StringBuilder();
_sbXml.AppendLine("<Request Type='' CRUD=''>");
_sbXml.AppendLine("<Users>");
_sbXml.AppendLine("<UserName>"+ usernameVariable +"</UserName>");
_sbXml.AppendLine("<Password>"+ passwordVariable +"</Password>");
_sbXml.AppendLine("</Users>");
DataTier.BeginRequest(_sbXml.ToString());
we tried abstracting things into methods but again we never solved the problem that we wanted to, just hid them somewhere.
So we concluded that strong typing is necessary for each request to
avoid any typo's,undesired behavior, avoid hand coded xml and
maintainable
. Hence the question
How can i abstract away this form of building xml's
XSD tool can generate class modelling xml data(Related post), is the class that is generated using the tool adaptive for long run?
Abstracting string xml to Typed classes is advisable? Has anyone had success doing something that i am trying to do now?Which did you feel comfortable with?
More
Above is just a single database call, we got same for all the database calls. We are into big mess maintaining for sure.
Extra
Using C# 2.0
.NET 2.0
SQL Server 2005
Visual Studio 2005
There are two problems here:
You're passing parameters to the stored procedures using XML, when stored procedures can take parameters in a perfectly normal way without using an intermediate layer
You're building your XML by hand. Please don't do that - .NET has plenty of good XML APIs, even though using .NET 2.0 means you can't use LINQ to XML.
So, I would suggest:
Get rid of the XML layer if you possibly can. I realize this may not be feasible.
Build the XML using APIs such as XmlDocument etc
You don't want the XML-building code littering your code, certainly - whether you need several different types for this is unclear from your post; it will depend on how much your requests vary.
(It's not really clear what you meant by "we concluded that a class would solve things" or "I saw the related post and generated class" so it's possible that I'm missing the point. If so, please edit your question to clarify.)
Personally I do not recommend using too much xml at the database; that is the least scalable part of your system (you can't scale it "out" cheaply), so rather than spending all its time processing xml, I would just use data in, data out - simple regular TSQL parameters and grids.
However!
That approach of building xml is pretty buggy actually - the values should be xml-escaped. But to answer the question - I would use LINQ-to-XML (XElement) or XmlSerializer. Probably the latter, i.e.
public class Request {
[XmlAttribute] public string Type {get;set;}
[XmlAttribute] public string CRUD {get;set;} // although I'd prefer an enum
public RequestUser Users {get;set;}
}
public class RequestUser {
public string UserName {get;set;}
public string Password {get;set;} // please use salted hash instead
}
then:
var req = new Request { Type = "", CRUD = "",
Users = new RequestUser { UserName = username, Password = password } };
var ser = new XmlSerializer(typeof(Request));
StringWriter sw = new StringWriter();
ser.Serialize(sw, req);
string xml = sw.ToString();
The main advantage I'd see here with XmlSerializer (over LINQ-to-XML) is that you can also use this to read back xml in that format, via Deserialize. However, LINQ-to-XML will also work nicely here:
var req = new XElement("Request",
new XAttribute("Type", ""),
new XAttribute("CRUD", ""),
new XElement("Users",
new XElement("UserName", username),
new XElement("Password", password)
)
);
var xml = req.ToString();
I need to serialize the strings from a resource file (.resx) into a JSON object. The resource file's keys are in flux and thus I cannot just create a C# object that accepts the appropriate values. It needs to be a dynamic solution. I am able to loop through the key-value pairs for the file, but I need an easy way to serialize them to JSON.
I know I could do:
Object thing = new {stringOne = StringResource.stringOne; ...}
But, I'd rather have something like:
Object generic = {}
foreach (DictionaryEntry entry in StringResource) {
generic.(entry.Key) = entry.Value
}
Or should I just create a custom JSON serializer that constructs the object piecemeal (i.e. foreach loop that appends part of the JSON string with each cycle)?
EDIT
I ended up writing a quick JSON serializer that constructs the string one field at a time. I didn't want to include a whole JSON library as this is the only use of JSON objects (for now at least). Ultimately, what I wanted is probably impractical and doesn't exist as it's function is better served by other data structures. Thanks for all the answers though!
If you're using C# 4.0, you should look at the magical System.Dynamic.ExpandoObject. It's an object that allows you to dynamically add and remove properties at runtime, using the new DLR in .NET 4.0. Here is a good example use for the ExpandoObject.
Once you have your fully populated ExpandoObject, you can probably easily serialize that with any of the JSON libraries mentioned by the other excellent answers.
This sounds like an accident waiting to happen (i.e. creating output prior to cementing the structure), but it happens.
The custom JSON serializer is a compelling option, as it allows you to easily move from your dictionary into a JSON format. I would look at open source libraries (JSON.NET, etc) to see if you can reduce the development time.
I also think setting up in a slightly more structured format, like XML, is a decent choice. It is quite easy to serialize from XML to JSON using existing libraries, so you avoid heavy customization/
The bigger question is what purposes will the data ultimately serve. If you solve this problem using either of these methods, are you creating bigger problems in the future.
Probably I would use JSON.NET and the ability to create JSON from XML.
Then, you could create an XML in-memory and let JSON.NET convert it to JSON for you. Maybe if you dig deeper into the API, there are other options, too.
Newtonsoft is a library that has all kinds of nifty JSON tools...among them, on-the-fly one-line serializer and deserializers...check it out, it's my favorite JSON library out there
http://james.newtonking.com/pages/json-net.aspx
If I remember correctly, it has a class that will convert JSON to a .NET object without having to create the .NET object first. Think it is in the Json.Convert class
The way I do it is:
var serialiser = new System.Web.Script.Serialization.JavaScriptSerializer();
string json = serialiser.Serialize(data);
context.Response.Write(json);
I'm thinking about throwing away my DB in my next project to simplify development/evolution.
One way to do it is not to leave the Objects realm at all and persist my objects by some kind of serialization. It would be nice to be able to edit the initial object state when the app is down, so a format like JSON would be great.
The problem is that JSON tools (like Java Jackson), or rather JSON itself, are not able to keep the references, so after deserializing object graph I can get more instances than I got before serialization - each reference to the same object gets new instance.
I've noticed JSPON but it doesn't seem to be alive.
What do you think about such approach - isn't it too simple to be possible? Or maybe I should use some OODB (although it would create additional configurational overhead and I want to keep it simple).
Most of the simple portable serializers (xml, json, protocol buffers) are tree serializers (not graph serializers), so you'll see this problem a bit...
You could perhaps try using a DTO tree that doesn't need the references? i.e. instead of:
Parent -(children)-> Child
<--(parent)--
you have (at the DTO level):
Parent {Key="abc"} -(child keys)-> {string}
Child {Key="def"} -(parent key)-> {string}
This should be usable with any tree serializer; but it does require extra (manual) processing.
There are graph-based serializers like .NET's DataContractSerializer (with graph-mode enabled; it is disabled by default); but this is non-portable.
The references issue should be simple enough to solve assuming you control the serialization - you'd simply save the objects giving each an id and then save the references in terms of those ids.
However, while I think you'd get a simple version working and I reckon you'd run into problems down the line. Things that spring to mind are:
What would happen as the code evolves and the classes change?
How would you support query operations, particularly indexing to make the queries fast?
How would you manage concurrent access?
How would you manage transactions?
How would it scale?
I don't think these problems are insurmountable but IMHO, relational databases are the way they are based on years of development and use in the wild and the OODBs that I've seen are not a realistic proposition at this time.
Also, there's a whole class of problem that the set based logic provided by relational databases is ideal for, let alone the power of SQL in refining the data-sets you load, which just isn't as easy in the object world. With the modern ORMs making life so easy these days I certainly would want to confine myself to either realm.
The latest version of Json.NET supports serializing references.
string json = JsonConvert.SerializeObject(people, Formatting.Indented,
new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
//[
// {
// "$id": "1",
// "Name": "James",
// "BirthDate": "\/Date(346377600000)\/",
// "LastModified": "\/Date(1235134761000)\/"
// },
// {
// "$ref": "1"
// }
//]
List<Person> deserializedPeople = JsonConvert.DeserializeObject<List<Person>>(json,
new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
Console.WriteLine(deserializedPeople.Count);
// 2
Person p1 = deserializedPeople[0];
Person p2 = deserializedPeople[1];
Console.WriteLine(p1.Name);
// James
Console.WriteLine(p2.Name);
// James
bool equal = Object.ReferenceEquals(p1, p2);
// true
I've found this SO question helpful. XStream seems to cope with references by using relative paths in tree structure to the first reference when finding next one, even for json ( see here ).
Simple apparently can deal with more complex object graphs, but XStream seems more popular, does JSON and will probably suit my needs (I won't be ever having cyclic references).
the itemscript project proposes a schema language based on JSON. itemscript schema describes data types. itemscript JAM is an application markup developed in itemscript.
the reference implementation includes a GWT client (Item Lens) and a column store (Item Store) that persists JSON data.
As long as you're not leaving .NET realm, why not use the serialization mechanisms that .NET offers? It can easily serialize your object graphs (private fields included) to a binary blob and back again. There is also a built-in mechanism for serializing to and from XML, although that has some limitations when it comes to private fields and stuff (you can work around that though). There are also attributes that specify that some fields are newer and may not be in the serialized stream. You'll have to deal with them being NULL yourself, but then - you'd have to do that anyway.
Added: Ah, yes, forgot to mention - I'm talking about System.Runtime.Serialization.Formatters.Binary.BinaryFormatter class.