XML til XSD til C#-klasse

by Israr Khan 17. februar 2011 23:12

NB: Posten ble ikke helt slik jeg forventet da YR sin XML var en smule kjip - det må finnes en enklere måte å gjøre dette på enn beskrevet nedenfor... Legg gjerne igjen en kommentar her eller på Twitter (@IsrarKhan) hvis du vet om noe bedre... (Ta utgangspunkt i YR sin XML..) 

Ok - la oss si du har lyst til å konsumere tjenestene til YR. Eksempel kan være å hente ned information om værdata for Oslo.

API-kallet til YR vil i dette tilfellet se omtrent slik ut:
http://api.met.no/weatherapi/locationforecast/1.8/?lat=59.57;lon=10.42



Resultatet fra dette kallet er et xml-dokument, og du ønsker å få dette omgjort til et CLR-objekt  - så hva gjør du?
Mer...

Tags: , , , , , , , ,

Deserialisering av meldinger fra BizTalk 2008

by Israr Khan 8. november 2010 13:16

    public static T Deserialize<T>(XmlDocument xml,
string rootName, string rootNamespace) where T : class, new()
{
T t;
DataContractSerializer dcs;
MemoryStream ms;

dcs = new DataContractSerializer(typeof(T),
rootName, rootNamespace, knownTypes);
using (ms = new MemoryStream())
{
xml.Save(ms);
ms.Seek(0, SeekOrigin.Begin);
t = (T)dcs.ReadObject(ms);
}

return t;
}

public static T Deserialize<T>(XmlDocument xml,
string rootName, string rootNamespace) where T : class, new()
{
using (var nodeReader = new XmlNodeReader(xml))
{
nodeReader.MoveToContent();
var xdokumentet = XDocument.Load(nodeReader);
DataContractSerializer ser = new DataContractSerializer(typeof(T),
rootName, rootNamespace, knownTypes);

var reader = xdokumentet.CreateReader();
var returobjekt = (T)ser.ReadObject(reader);
reader.Close();
return returobjekt;
}
}

Har opplevd litt rar oppførsel ved deserialisering av XmlDocument fra BizTalk i en av hjelpekomponentene våre her på prosjektet.

Begge operasjonene våre ovenfor fungerer smertefritt når de kalles direkte fra C#-kode, og også med nøyaktig samme XmlDocument som BizTalk sender inn.

Når det kalles fra BizTalk på den andre siden, feiler begge.

For deserialiseren som bruker memorystream, blir string.empty konvertert til "\n\n\n", noe som medfører at sjekk på f.eks. string.IsNullOrEmpty vil feile, og også at disse verdiene vil bli lagret i databaser o.s.v.

For den andre deserialiseren hvor XmlDocumentet blir konvertert til et XDocument slipper vi unna problematikken med string.empty, men da får vi et litt mer pussig resultat:
Først gang komponenten blir kalt fungerer deserialiseringen, andre gang komponenten blir kalt feiler operasjonen med følgende feilmelding:

"...at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp) Additional error information: Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. Exception type: SerializationException Source: System.Runtime.Serialization Target Site: Void HandleMemberNotFound(System.Runtime.Serialization.XmlReaderDelegator, System.Runtime.Serialization.ExtensionDataObject, Int32) The following is a stack trace that identifies the location where the exception occured at System.Runtime.Serialization.XmlObjectSerializerReadContext.HandleMemberNotFound(XmlReaderDelegator xmlReader, ExtensionDataObject extensionData, Int32 memberIndex)"

Har foreløpig ikke klart å løse opp i dette på en god måte - men problemet forsvinner tilsynelatende hvis du oppretter et nytt XmlDocument basert på det eksisterende XmlDocument-et sin InnerXml.toString(). Sært problem - og foreløpig står det uløst. Gi gjerne en tilbakemelding hvis du vet hva som faktisk skjer her... (Obs: Husk at begge operasjonene fungerer uten problemer når de kalles direkte fra C#)

Posted using CodePoster"

Tags: , , ,

Koding

Om meg

Kodeverk.net er drevet av .Net-utvikler Israr Khan.

Han jobber som gruppeleder og  seniorkonsulent for Capgemini Norge.

Hans fokusområder er alt innenfor .Net-verden, og har foreløpig tilgode å finne noe som han ikke finner av interesse innenfor teknologien. Han er drevet av genuin interesse for teknologi og lever for faget.


 

View Israr Khan's profile on LinkedIn

Month List