I am changing my ASP.NET app to use a web farm. To do this, I need to change the session state from in-proc to a State Server. To do this, it is my understanding that the classes that are used must be marked as serializable. How can you tell if that is possible with a class? Will you get an error at compile time if it is not possible?
In answer to your first question about how to tell whether or not a class is serializable, see the following discussion. How to check if an object is serializable in C#
Unfortunately, .net has surprised me with bizarre behavior when I try to serialize objects that I think should be serializable.
For example, in my WCF projects, I can serialize and transmit DataSet objects. However, if I try to serialize and transmit DataTable objects, I end up with a blank DataTable. It took me a while to track that one down.
Therefore, I would suggest that you do at least some rudimentary testing of what happens when you try to serialize custom classes.
You won't get a compile-time exception, since compile-time doesn't really know whether the objects will need to be serialized. You'll get a SerializationException when IIS attempts to serialize your objects.
You can write a short snippet that attempts to serialize and de-serialize the objects in question... use a BinaryFormatter to do the serialization, and a FileStream to write to.
The ObjectBrowser will tell you if an existing class implements ISerializable. If you're looking at your own objects to serialize, keep in mind that classes must really be designed for serialization if they are intended to be serialized, otherwise there are gotchas. For example, from the MSDN help:
The order in which objects are deserialized cannot be guaranteed. For example, if one type references a type that has not been deserialized yet, an exception will occur.
I recommend reading up in ISerializable... here's a link: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx
EDIT: Here is a simple example of serialization and deserialization... just replace the Exception I'm serializing with your own objects:
BinaryFormatter formatter = new BinaryFormatter();
Exception serializedException = new Exception("Testing serialization");
Exception deserializedException;
using (FileStream fileStream = new FileStream(#"C:\SerializationTest.txt", FileMode.CreateNew)) {
formatter.Serialize(fileStream, serializedException);
}
using (FileStream readStream = new FileStream(#"C:\SerializationTest.txt", FileMode.Open)) {
deserializedException = formatter.Deserialize(readStream) as Exception;
}
if (deserializedException != null) {
throw deserializedException;
}
Related
I have this situation, I am creating a Web Service in C# where I need to consume a SOAP Web Service, which gives me an XML response back, I need to serialize this XML response and save it to a table in the database.
I have tried the to call the XML in Postman and it worked fine with a
200 OK status
, but I need how to serialize this reponse and save it to the database.
And then I have tried to write this:
public void CreateFilter(Student student)
{
var XML = XmlSerialization <Student> (student);
ConnectDataBase db = new ConnectDataBase();
SqlCommand cmd = new SqlCommand("sp_Student");
cmd.Parameters.Add("#name", SqlDbType.VarChar).Value = student.name;
cmd.Parameters.Add("#surname", SqlDbType.VarChar).Value = student.surname;
cmd.Parameters.Add("#subject", SqlDbType.VarChar).Value = student.subject;
cmd.Parameters.Add("#student", SqlDbType.Xml).Value = XML;
}
Any thoughts on how to get a response from the Web Service I have to consume, and then serialize the response I'm getting back and then save the serialization on the database?
Thank you in advance
Well, you have a couple of options really. Essentially, if you aren't leveraging an ORM (like Hibernate or some such), you want to:
Grab the XML payload
Get that deserialized into an object instance so you can work with it
Pick out the data you are interested in and persist it
Step 2 is essentially writing a class (or tree of classes) that mimmicks the field structure of the XML, then asking a library nicely to parse the XML state into an instance of that class. This then makes it easy to work with for you.
You can either leverage the the native deserialization as per:
https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer.deserialize?view=net-6.0
Or, just for arguments sake alternatively you could use a modern serialization library. There isn't much of a good choice when it comes to XML and C#, so the main one I can think of that will get you from point a to point b is Json.NET:
https://www.newtonsoft.com/json
This library, though predomenantly pushed as an all-in-one object mapper for JSON is also able to translate between XML and Json:
https://www.newtonsoft.com/json/help/html/ConvertingJSONandXML.htm
Depending on how much of a fight the native deserializer puts up (defining the schema can be a bit of a pain, bloody SOAP am I right), it might be easier to use Json.NET to hoover up the XML, convert it to JSON, then deserialize that json as an object.
This gives you a 2-step deserialization process which isn't ideal, but it's not such a bad thing either as you get to work with the "nice" library and not have to fight the old baked in xml serialization stuff.
The choice is yours really. I'd give the first option a good go first then if that puts up too much of a fight you have Json.NET to fall back on :)
I'm new to PostSharp and trying to do something that that has me vexed, but seems simple:
I'm trying to use Json.Net to serialize and deserialize an instance of MethodInterceptionArgs
Serialization work fine:
string strArgs = JsonConvert.SerializeObject(args);
But I seem to be missing something when deserializing it: What class should I be deserializing it to? MethodInterceptionArgs is abstract, so I don't think that will work.
I could create my own concrete implementation, but that seems ilke it shouldn't be necessary (and I keep getting an error that MethodInterceptionArgs does not contain a constructor that takes zero arguments)
MethodInterceptionArgs is not meant to be serialized. You should copy the relevant pieces of information into another object and serialize it.
Currently one my DAL methods uses the ExecuteXmlReader command to read and append to a StringBuilder object and return XML as a string. I realize this isn't the best way to handle very large files (200MB+) as when the ToString() method is called on StringBuilder it throws an out of memory exception.
There are certain constraints I need to adhere by - I cannot return a XMLReader out of the DAL (db connection stays open, etc), this XML will have to be written to file and keeping it's formatting for various reasons, currently using an XMLTextWriter's WriteRaw method for that purpose.
What would be the best data type to return from the DAL to make all this work with large XML files?
I explored the options of using a DataSet, Memory Stream and a Byte Array - but each have their shortfalls. I am looking for the best practice and some code samples would be helpful.
You can use XDocument the work with your xml files. You can use linq to xml to query through your elements. An example is below:
XDocument document = XDocument.Load("http://someurl.com/data.xml");
var elements = from element in document.Descendants("SomeElement")
select element;
Console.WriteLine(elements.First().Value);
If you also get the out of memory exception with this (i think you will), then you should take a look at the following post:
http://james.newtonking.com/archive/2007/12/11/linq-to-xml-over-large-documents.aspx
More information about the XDocument class can be found here:
http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx
and here
http://www.hookedonlinq.com/Print.aspx?Page=LINQtoXML5MinuteOverview
Good luck!
Basically I want to make my script service only serialise properties that are not null on an array of object I am returning... So this..
{"k":"9wjH38dKw823","s":10,"f":null,"l":null,"j":null,"p":null,"z":null,"i":null,"c":null,"m":0,"t":-1,"u":2}
would be
{"k":"9wjH38dKw823","s":10,"m":0,"t":-1,"u":2}
Does anyone know if this is possible?
Basically the reason for this is because null values are for unchanged properties. A local copy is kept in the javascript that is just updated to reduce traffic to the server. Change values are then merged.
You can create a custom JavaScriptConverter class for the JSON serialization process to use to handle your object, and then put the necessary logic in the Serialize method of that class to exclude the properties that are null.
This article has a clear step-by-step discussion of the process involved in creating it.
You probably would not need to actually implement the Deserialize method (can throw a NotImplementedException) if you are not passing that type of object in as an input parameter to your web services.
I'm building an ASP.NET (2.0, no, I can't change it) site with NHibernate, and have a custom JSON converter so I can not-serialize properties I want hidden from the client. This lets me just return the objects, and never have to worry about their serialized values - they're always secure.
Unfortunately, it appears that if I use query.FutureValue<class>(), the object that gets serialized is first the NHibernate.Impl.FutureValue<class> and not my entity, which means I get JSON that looks like this if I throw it in a dictionary and return it to the client:
{key: { Value: { /* my serialized object properties */ } }
Previously I discovered that I can't get any interfaces to work in ASP's JavaScriptConverter implementations... only regular or abstract classes. So returning typeof(IFutureValue<MyBaseClass>) as a supported type means my converter is completely ignored. I can catch MyBaseClass, because I refactored things earlier to use an abstract base instead of an interface, but not the interface.
And then I discover that the FutureValue implementation in .Impl is internal to the assembly, or some other such nonsense that only serves to make my .NET experience even more painful. So I can't use typeof(FutureValue<MyBaseClass>) to handle it all, because FutureValue exists only in my debugging sessions.
Is there a way to get the class type out of the assembly? Or a way to convince ASP that interfaces do in fact have uses? Or might there be some superclass I can access that would let me get around the whole issue?
Help! I like my Futures, it lets me batch a whole heck-ton of calls at once!
(if something isn't clear, or you want more code, by all means, ask! I can post quite a bit.)
If I'm understanding you correctly, it seems you are mixing things a together a little bit.
It sounds like you're trying to serialize an instance of query.FutureValue<class>(), which unsurprisingly gives you just that: a JSON object where the Value fields has JSON representing your entity.
To me it sounds like you really want to just serialize query.FutureValue<class>().Value.
Using NHibernate futures like this gives you little benefit though, so you're probably after something like:
var future1 = query1.FutureValue<SomeEntity>();
var future2 = query2.FutureValue<AnotherEntity>();
var json1 = serializer.Serialize(future1.Value); //<BAM! Multi-query gets fired!
var json2 = serializer.Serialize(future2.Value);
Does that make sense?