There was an error in serializing body of message - c#

I am getting exception on trying to consume a service (3rd party), below is the stack trace for the exception.
StackTrace " at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)\r\n at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle)\r\n at System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, Object returnValue, Object[] parameters)\r\n at System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)" string
Earlier it was working fine, but after updating the service reference it started throwing the above exception.
Also tried the solution described in the below link, but was of no help.
There was an error in serializing body of message
Appreciate your kind help in resolving the same.
Below is the code that i am using
//reportContent is having xml data as string.
XmlDocument xmlReportDocument = new XmlDocument();
xmlReportDocument.LoadXml(reportContent);
RequestHandlerProcessSoapClient ws = new RequestHandlerProcessSoapClient();
ws.ClientCredentials.UserName.UserName = _reportFormatData.User;
ws.ClientCredentials.UserName.Password = _reportFormatData.Password;
///Create the request
myRequest request = new myRequest();
request.Requestor = new Requestor();
request.Requestor.ApplicationID = _reportFormatData.ApplicationId;
request.Requestor.Stylesheet = template;
request.Requestor.Environment = _reportFormatData.Environment;
request.Payload = xmlReportDocument;
///Setup the attachements
myAttachmentRequest attachmentrequest = new myAttachmentRequest();
attachmentrequest.setRequest = request;
myResponse serResp = ws.renderDocument(attachmentrequest)//Error shows up in this line.

Finally found the solution to this question. After adding a service reference, by default payload property in Reference.cs was returning a value of type 'Object', and this i changed it to return System.Xml and it clicked.

Related

Using Fonet to Convert XSL-FO to PDF Getting System Exception: Unknown enumerated value for property 'text-decoration': no-underline

I'm using Fonet to convert XSL-FO to Pdf. Below is the code I'm using C# on Visual Studio
FonetDriver driver = FonetDriver.Make();
driver.Render("C:\\XSLT\\Input\\input.fo", "C:\\XSLT\\Output\\result.pdf");
Getting Exception:
System.SystemException: **'System.SystemException: Unknown enumerated value for property 'text-decoration': no-underline**
at Fonet.FonetDriver.FireFonetError(String message)
at Fonet.Fo.EnumProperty.Maker.CheckEnumValues(String value)
at Fonet.Fo.Properties.TextDecorationMaker.CheckEnumValues(String value)
at Fonet.Fo.PropertyMaker.Make(PropertyList propertyList, String value, FObj fo)
at Fonet.Fo.PropertyListBuilder.MakeList(String ns, String elementName, Attributes attributes, FObj parentFO)
at Fonet.Fo.FOTreeBuilder.StartElement(String uri, String localName, Attributes attlist)
at Fonet.Fo.FOTreeBuilder.Parse(XmlReader reader)'
Example <fo:block> in my input.fo
Help!

Census Geocoder JSON output convert to Xml dataset using JSON.net in C#

I am creating a .Net app in Visual Studio 2012 that queries an address table in my SQL dB and uses the Census Geocoding API to return the specific MSA for each address. I have existing code for the dB query, but I am having trouble with converting the Json output of the Census API to an Xml dataset. I am using Json.net to serialize the json output and then deserialize to .net in order to load into an XmlDocument. Unfortunately, I keep getting an XmlException error:
Data at the root level is invalid. Line 1, position 1
Details:
System.Xml.XmlException was unhandled HResult=-2146232000
Message=Data at the root level is invalid. Line 1, position 1.
Source=System.Xml LineNumber=1 LinePosition=1 SourceUri=""
StackTrace:
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
at System.Xml.XmlDocument.Load(XmlReader reader)
at System.Xml.XmlDocument.LoadXml(String xml)
at ConsoleApplication1.Program.Main(String[] args) in c:\Users\jdsmith\Documents\Visual Studio
2012\Projects\C#\MSA_Application_v2\MSA_Application_v2\Model\Program.cs:line
54
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart() InnerException:
I believe either the Json or the Xml need to be formatted further, but I don't know how. Also, I'm sure I am making this too difficult on myself...if there is a better way, I am all ears.
Here is the sample geolookup I am using to test:
http://geocoding.geo.census.gov/geocoder/geographies/address?street=4600+Silver+Hill+Rd&city=Suitland&state=MD&benchmark=Public_AR_Census2010&vintage=Census2010_Census2010&layers=14&format=json
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Data;
using System.Net;
using System.IO;
using System.Xml;
using System.Runtime.Serialization.Json;
using System.Xml.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace ConsoleApplication1
{
class Program
{
private static string geoRT = "geographies";
private static string geoST = "address";
private static string geoStreet = "4600+Silver+Hill+Rd";
private static string geoCity = "Suitland";
private static string geoState = "MD";
private static string geoZip = "20746";
private static string geoBM = "Public_AR_Census2010";
private static string geoVin = "Census2010_Census2010";
private static string geoLayer = "all";
private static string geoFormat = "json";
static void Main(string[] args)
{
StringBuilder geoRelURI = new StringBuilder();
geoRelURI.AppendFormat(#"{0}/{1}?street={2}&city={3}&state={4}&zip={5}&benchmark={6}&vintage={7}&layers={8}&format={9}"
, geoRT, geoST, geoStreet, geoCity, geoState, geoZip, geoBM, geoVin, geoLayer, geoFormat);
Uri geoBaseURI = new Uri("http://geocoding.geo.census.gov/geocoder/");
Uri geoURI = new Uri(geoBaseURI, geoRelURI.ToString());
//Console.WriteLine(geoURI);
//Console.ReadLine();
WebRequest geoRequest = WebRequest.Create(geoURI);
WebResponse geoResponse = geoRequest.GetResponse();
Stream geoDataStream = geoResponse.GetResponseStream();
StreamReader geoReader = new StreamReader(geoDataStream);
string geoString = geoReader.ReadToEnd();
var jsonConvert = JsonConvert.SerializeObject(geoString);
string jsonString = jsonConvert.ToString();
var xmlConvert = JsonConvert.DeserializeObject(jsonString);
string xmlString = xmlConvert.ToString();
XmlDocument geoXMLDoc = new XmlDocument();
geoXMLDoc.LoadXml(xmlString);
XmlWriterSettings xmlSettings = new XmlWriterSettings();
xmlSettings.Indent = true;
XmlWriter geoXMLWriter = XmlWriter.Create("geoXML.xml", xmlSettings);
geoXMLDoc.Save(geoXMLWriter);
Console.Write("<BR>" + geoXMLDoc.OuterXml);
//Console.WriteLine(xmlString);
//Console.ReadLine();
geoDataStream.Close();
geoResponse.Close();
}
}
}
First of all, you are passing a JSON string to geoXMLDoc.LoadXml(). That's not going to work. What you want to do is to convert the JSON to an XmlDocument via JsonConvert.DeserializeXmlNode.
However, some of your JSON properties contain characters that are invalid for use in XML names, in specific whitespace:
{"Census Blocks":[{"BLKGRP":"1",
It seems that this causes DeserializeXmlNode to throw an exception. Thus you'll need to rename the names:
var obj = JObject.Parse(geoString);
foreach (var fix in (from property in obj.Descendants().OfType<JProperty>()
let newName = XmlConvert.EncodeLocalName(property.Name.Replace(" ", ""))
where newName != property.Name
select new { Old = property, New = new JProperty(newName, property.Value) })
.ToList())
{
fix.Old.Replace(fix.New);
}
var xmldoc = JsonConvert.DeserializeXmlNode(obj.ToString());
Need you to post what you are attempting to load into the XmlDocument. That is where you are hitting your problem. If you are trying to load the JSON you get from the web call it won't work, if you are (as I suspect) using JSON.Net to convert the JSON to Xml, the Xml is missing something that the XmlDocument wants. Could be the Xml declaration line, or your xml fragment may not include a root node. Without seeing the xml we have no way to tell specifically what is missing or malformed.

Deserialization error - object reference not set

I am trying to deserialize an xml string in c#3.5, the code below does work in c# 4.0.
When I try to run in the code in c#3.5 I get an Object reference not set to an instance of an object exception when the code tries in initialize the XmlSerializer.
Any help would be appreciated.
string xml = "<boolean xmlns=\"http://schemas.microsoft.com/2003/10/serialization/\">false</boolean>";
var xSerializer = new XmlSerializer(typeof(bool), null, null,
new XmlRootAttribute("boolean"),
"http://schemas.microsoft.com/2003/10/serialization/");
using (var sr = new StringReader(xml))
using (var xr = XmlReader.Create(sr))
{
var y = xSerializer.Deserialize(xr);
}
System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="System.Xml"
StackTrace:
at System.Xml.Serialization.XmlSerializer..ctor(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, String defaultNamespace, String location, Evidence evidence)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, String defaultNamespace)
....
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
It looks like in .NET 3.5 it doesn't like the Type[] extraTypes to be null. Just pass an empty Type[] instead, for example new Type[0], or just simply:
var xSerializer = new XmlSerializer(typeof(bool), null, Type.EmptyTypes,
new XmlRootAttribute("boolean"),
"http://schemas.microsoft.com/2003/10/serialization/");
As a side note: when creating XmlSerializer instances using non-trivial constructors (like this one), it is very important to cache and re-use the serializer - otherwise it'll generate an in-memory assembly per serializer, which is a: bad for performance, but b: causes a severe memory leak (assemblies cannot be unloaded).

ASP.NET SessionState SQLServer mode - System.Xml.XmlBoundElement is not marked as serializable

I am currently modifying an ASP.NET (3.5) application to run in SQLServer SessionState
mode. In the existing code, we have a serialized dataset that is currently stored in
the Session using C#. I have a property that I use to extract this serialized dataset
and load it into a XmlDataDocument. My property is "something" like this:
public abstract class TransCommand
{
public static XmlDataDocument TransDoc
{
get
{
XmlDataDocument doc = null;
if (Session["DataSetStore"] != null)
{
DataSet tds3 = new DataSet();
MemoryStream tms3 = new MemoryStream(HttpContext.Current.Session["DataSetStore"] as byte[]);
doc = new XmlDataDocument();
doc.LoadXml(System.Text.Encoding.UTF8.GetString(tms3.ToArray()));
}
return doc;
}
set
{
Session["DataSetStore"] = System.Text.Encoding.UTF8.GetBytes(value.OuterXml);
}
}
This works great except when I try to append an XmlNode to a node created from this
TransDoc method.
public class AddChildren
{
XmlDataDocument doc = TransactionCommand.TransactionDoc;
doc.DataSet.EnforceConstraints = false;
XmlNode dataNode = doc.SelectSingleNode("//WebServiceResponse/Data");
......
ArrayList lstNewInfants = new ArrayList();
1stNewInfants.add(newInfants); //Adding new Infants XmlNodes into an arraylist.
foreach (XmlNode nodInfant in lstNewInfants)
{
dataNode.AppendChild(nodInfant);
}
doc.DataSet.EnforceConstraints = true;
TransactionCommand.TransactionDoc = doc; //Adds the modified doc back into the session
After appending this node, I receive the following exception after the Databind of the
next page aspx page encountered:
Error Message:Type 'System.Xml.XmlBoundElement' in Assembly 'System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.
Stack Trace: at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
at System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer)
Any Ideas?

Intermittent errors while de-serializing object from XML

I have a program that takes objects stored as XML in a database (basicly a message queue) and de-serializes them. Intermittently, I will get one of the following errors:
System.Runtime.InteropServices.ExternalException: Cannot execute a program. The command being executed was "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe" /noconfig /fullpaths #"C:\Documents and Settings\useraccount\Local Settings\Temp\lh21vp3m.cmdline".
at System.CodeDom.Compiler.Executor.ExecWaitWithCaptureUnimpersonated(SafeUserTokenHandle userToken, String cmd, String currentDir, TempFileCollection tempFiles, String& outputName, String& errorName, String trueCmdLine)
at System.CodeDom.Compiler.Executor.ExecWaitWithCapture(SafeUserTokenHandle userToken, String cmd, String currentDir, TempFileCollection tempFiles, String& outputName, String& errorName, String trueCmdLine)
at Microsoft.CSharp.CSharpCodeGenerator.Compile(CompilerParameters options, String compilerDirectory, String compilerExe, String arguments, String& outputFile, Int32& nativeReturnValue, String trueArgs)
at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames)
at Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options, String[] sources)
at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources)
at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource(CompilerParameters options, String[] sources)
at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence)
at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies)
at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
.....
Or I'll get this one:
System.InvalidOperationException: Unable to generate a temporary class (result=1).
error CS0016: Could not write to output file 'c:\Documents and Settings\useraccount\Local Settings\Temp\nciktsd7.dll' -- 'Could not execute CVTRES.EXE.'
at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence)
at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies)
at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
....
The program process thousands of messages a day successfully, but I only get these errors maybe 2 or 3 times a day. They don't appear to be correlated to any specific kind of message, just completely random.
Any idea what causes those errors and how to fix it?
ETA - Here's the code that is causing the errors, in case that helps:
public class MessageContextBuilder<T> where T : MessageContextBase
{
private static IDictionary<string, XmlSerializer> SerializerCache { get; set; }
public ILog Logger { get; set; }
public MessageContextBuilder() {
if (SerializerCache == null) SerializerCache = new Dictionary<string, XmlSerializer>();
Logger = LogContextManager.Context.GetLogger<MessageContextBuilder<T>>();
}
public T BuildContextFromMessage(IEmailQueueMessage msg) {
XmlSerializer serializer = GetSerializer(typeof(T));
XmlReader r = XmlReader.Create(new StringReader(msg.MessageDetails));
if (serializer.CanDeserialize(r)) {
T rval = (T)serializer.Deserialize(r);
rval.EmailAddress = msg.EmailAddress;
rval.LocaleID = msg.LocaleID;
rval.StoreID = msg.StoreID;
rval.MessageID = msg.UniqueKey;
return rval;
} else {
throw new ArgumentException("Cannot deserialize XML in message details for message #" + msg.UniqueKey);
}
}
public XmlSerializer GetSerializer(Type t) {
if (!SerializerCache.ContainsKey(t.FullName)) {
SerializerCache.Add(t.FullName, new XmlSerializer(t)); // Error occurs here, in XmlSerializer constructor, intermittently
}
return SerializerCache[t.FullName];
}
}
You can pre-create serializers: http://msdn.microsoft.com/en-us/library/bk3w6240%28v=VS.100%29.aspx Just give it a try. The next canonical candidate for such problems is your virus scanner. Your tool is writing to disc while creating serializers. I have seen virus scanner producing all kind of strange errors in such situations.
XmlSerializer is supposed to be thread safe.
Even if that's the case, you can notice the behavior you are getting is in both cases failing at: XmlSerializer..ctor(Type type)
Given that, it seriously look like a multi-threading limitation trying to create serializers.
I suggest to take this code you have:
public XmlSerializer GetSerializer(Type t) {
if (!SerializerCache.ContainsKey(t.FullName)) {
SerializerCache.Add(t.FullName, new XmlSerializer(t)); // Error occurs here, intermittently
}
return SerializerCache[t.FullName];
}
And implement a lock on the Add. This way you are only creating 1 serializer at a time. The hit is small if you aren't processing tons of different types.
Note that you need the lock anyway, as the way it is you could get duplicate exceptions when 2 types try to be added at the same time.
static object serializerCacheLock = new object();
public XmlSerializer GetSerializer(Type t) {
if (!SerializerCache.ContainsKey(t.FullName))
lock(serializerCacheLock)
if (!SerializerCache.ContainsKey(t.FullName)) {
SerializerCache.Add(t.FullName, new XmlSerializer(t));
}
return SerializerCache[t.FullName];
}
If the above still isn't enough, I'd try with a read/write lock on serializer constructor vs. serializers usage. Line of thought being that maybe the multi-threading issue is worth than 2 ctors running at the same time.
All above is a Huge guess, but if it were me I'd definitely confirm is not that.
For the first error (cannot execute a program), you might be running into the same XmlSerializer bug that we ran into. It turns out XmlSerlializer throws that exception when Directory.CurrentDirectory is set to a folder that no longer exists.
Our specific situation is different than yours, but I'll give the details in case it helps shed light on what might be happening for you, or it helps anyone else. In our case, a small number of our customers would get that error after launching our WinForms application directly from the installer, i.e. they chose the "run now" option after installing or upgrading. (Unclear why it happened to some but not others). What we suspect is happening is that our installer (InstallAware) occasionally starts our application with the current directory set to a folder that no longer exists, or is about to be deleted. To test this theory, I wrote a test app which simulates launching from the installer:
string dir = #"C:\Users\me\Documents\Temp\WillBeDeleted";
Directory.CreateDirectory(dir);
Directory.SetCurrentDirectory(dir);
Process.Start(#"C:\Program Files (x86)\...\our.exe");
Directory.SetCurrentDirectory(#"C:\"); // otherwise, won't be able to delete
Directory.Delete(dir);
Sure enough, as soon as the launched application created a new instance of XmlSerializer, the exception would be thrown. I put in trace statements to show the result of GetCurrentDirectory(), and indeed it was set to the WillBeDeleted folder. The fix was to SetCurrentDirectory to a valid location during application initialization, before any serialization took place.
This is a sign that you are not caching your serialisers which is not good at all => it leads to memory leak and I suspect you will experience this.
Remember that .NET generates code and compiles them into assemblies every time you create a serialiser.
Always create your serialisers and then cache them.
Here is a sample:
public class SerialiserCache
{
private static readonly SerialiserCache _current = new SerialiserCache();
private Dictionary<Type, XmlSerializer> _cache = new Dictionary<Type, XmlSerializer>();
private SerialiserCache()
{
}
public static SerialiserCache Current
{
get { return _current; }
}
public XmlSerializer this[Type t]
{
get
{
LoadIfNecessary(t);
return _cache[t];
}
}
private void LoadIfNecessary(Type t)
{
// double if to prevent race conditions
if (!_cache.ContainsKey(t))
{
lock (_cache)
{
if (!_cache.ContainsKey(t))
{
_cache[t] = new XmlSerializer(typeof(T));
}
}
}
}
}

Categories

Resources