Thursday, 22 August 2013

xml deserialization override namespace

xml deserialization override namespace

I'm parsing xml based on an xsd using the generated c# class. The provider
of the XML updated the schema but some responses I am getting do not use
the new schema - the main thing that changed was the namespace.
So the xmlns= tag at the root level of the XML is incorrect for the
generated c# class to deserialize and I get an exception saying that the
xmlns= is unexpected. If I manually change the namespace to match that of
the schema the xml deserializes just fine as I would expect.
So I embarked on a journey to override the namespace. Here's my code
attempt: * This compiles and runs but yields the standard error that the
tag is unexpected and that there is an error in the XML
If I uncomment the attrs.Xmlns = true;
Then at the time of creation of the serializer (two lines down) I get an
operation exception that says:
System.InvalidOperationException was unhandled
Message="There was an error reflecting type 'MessageType'."
Source="System.Xml"
StackTrace:
at
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType,
XmlAttributes a, Boolean repeats, Boolean openModel,
RecursionLimiter limiter)
at
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType, XmlAttributes
a, RecursionLimiter limiter)
at
System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel
model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter
limiter)
at
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type
type, XmlRootAttribute root, String defaultNamespace)
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)
at ConsoleApplication2.Program.Main(String[] args) in C:\Documents and
Settings\Administrator\My Documents\Visual Studio 2008\Projects\10.6
tester\ConsoleApplication2\Program.cs:line 194
at System.AppDomain._nExecuteAssembly(Assembly 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.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.InvalidOperationException
Message="XmlRoot and XmlType attributes may not be specified for
the type MessageType."
Source="System.Xml"
StackTrace:
at
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType,
XmlAttributes a, Boolean repeats, Boolean openModel,
RecursionLimiter limiter)
InnerException:
SO - how do I make this work - without changing the generated class
because eventually data will come in with the right namespace - and
without changing the XML received? How can I make the override work?
* code *
var attrs = new XmlAttributes();
/* Create an XmlRootAttribute to override the XmlRoot in-line attr.
The override will use no namespace. */
var attr = new XmlRootAttribute("Message");
// attr.ElementName = "Message";
attr.Namespace = "http://www.ncpdp.org/schema/SCRIPT";
// set the XmlRoot on the XmlAttributes collection.
attrs.XmlRoot = attr;
// Create the XmlAttributeOverrides object.
var o = new XmlAttributeOverrides();
/* Map the attributes collection to the thing being
overriden (the class). */
// attrs.Xmlns = true;
o.Add(typeof(MessageType), attrs);
//
XmlSerializer serr = new XmlSerializer(typeof(MessageType),o);
// XmlSerializer sexx = new XmlSerializer(
// deserialize
try
{
rsp = (MessageType)serr.Deserialize(reader);
XmlSerializer serx = new XmlSerializer(typeof(MessageType));
TextWriter w1 = new StreamWriter(@"c:\ssresp.xml");
serx.Serialize(w1, rsp);
w1.Close();
string retFile;
// UpdatePharmacyItem(rsp, "PhoneNumbers", "Update",
"9314421118", "PH");
// UpdatePharmacyItem(rsp, "PhoneNumbers", "Update",
"9316256234", "HO");
// UpdatePharmacyItem(rsp, "PhoneNumbers", "Delete",
"", "FX");
retFile = ParseResponse(rsp);
}
catch (Exception e)
{
reader.BaseStream.Position = 0;
string responseFromServer = reader.ReadToEnd();
StreamWriter SW;
SW = File.CreateText(@"C:\raw.txt");
SW.WriteLine(responseFromServer);
SW.Close();
reader.Close();
return;
}
}
The XML - (With the wrong namespace)
<Message version="010" release="006"
xmlns="http://www.surescripts.com/messaging"><Header> <To
Qualifier='P'>1405275</To><From Qualifier='M'>surescripts</From>
<MessageID>b2134cc16b804bf9846c98ca19ea52c5</MessageID><RelatesToMessageID>2013-08-22-
16.34.10.656250</RelatesToMessageID><SentTime>2013-08-22T16:33:59.4Z</SentTime>
<SenderSoftware><SenderSoftwareDeveloper>Surescripts</SenderSoftwareDeveloper>
<SenderSoftwareProduct>Message Processing</SenderSoftwareProduct>
<SenderSoftwareVersionRelease>2013.3</SenderSoftwareVersionRelease></SenderSoftware></Header>
<Body><Status><Code>002</Code></Status></Body></Message>

No comments:

Post a Comment