Quite straights forward issue, but still can't figure out...
I'm trying to deserialize XML which contains collection of XmlElements. I would like to deserialize the elements (First and second).
The most important elements are the ones in the ImportantNode.
The third is less important.
The failure is at the Deserialization method.
This is the xml:
<configuration>
<objects>
<!-- this is a comment -->
<First>
<param name="Name" type="string">FirstName</param>
<param name="Type" type="string">FirstType</param>
<SomeElement>
<SomeElement1>
<param name="Name" type="string">AAA</param>
<param name="Name2" type="string">BBB</param>
</SomeElement1>
</SomeElement>
<param name="param1" type="string">1</param>
<param name="param2" type="int">2</param>
<param name="param3" type="float">3</param>
<ImportantNode>
<ImportantChildNode1>
<param name="minValue" type="float">1</param>
<param name="maxValue" type="float">100</param>
</ImportantChildNode1>
<ImportantChildNode2>
<param name="minValue" type="float">1</param>
<param name="maxValue" type="float">100</param>
</IR>
</ImportantNode>
<elements>
<element>
<param name="paramName1" type="bool">true</param>
</element>
</elements>
</First>
<second>
<param name="Name" type="string">2</param>
<param name="Type" type="string">3</param>
<ImportantNode>
<ImportantChildNode1>
<param name="minValue" type="float">2</param>
<param name="maxValue" type="float">20</param>
</ImportantChildNode1>
<ImportantChildNode2>
<param name="minValue" type="float">3</param>
<param name="maxValue" type="float">30</param>
</IR>
</ImportantNode>
</second>
<third>
<param name="Name" type="string">3</param>
<param name="Type" type="string">4</param>
<AAAA>
<param name="DDD" type="string">XXX</param>
</AAAA>
<BBBB>
<param name="DDD" type="string">ZZZ</param>
</BBBB>
<param name="Param1" type="string">6</param>
<param name="Param2" type="string">301</param>
</third>
</objects>
</configuration>
This is the related classes:
[Serializable]
[XmlRoot(ElementName = "ImportantNode")]
public class ImportantNode
{
[XmlElement(ElementName = "ImportantChildNode1")]
public Param ImportantChildNode1Params { get; set; }
[XmlElement(ElementName = "ImportantChildNode2")]
public Param ImportantChildNode2Params { get; set; }
}
public class Param
{
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
/*
[XmlAttribute(AttributeName = "type")]
public string type { get; set; }*/
[XmlText]
public string Value { get; set; }
}
[Serializable]
public class DeserializeObject
{
[XmlArrayItem("param")]
public List<Param> Params { get; set; }
[XmlElement (ElementName ="ImportantNode")]
public ImportantNode ImportantNodeParams { get; set; }
}
And this is the relevant code:
IEnumerable<DeserializeObject> DeserializeObjectsList;
XmlReaderSettings readSettings = new XmlReaderSettings();
readSettings.IgnoreComments = true;
string filePath = "<xml file path>";
//using (XmlReader reader = XmlReader.Create(filePath, readSettings)
XmlReader reader = XmlReader.Create(filePath, readSettings);
XmlDocument filedoc = new XmlDocument();
filedoc.Load(reader/*filePath*/);
//using var fileStream = new FileStream(filePath, FileMode.Open);
XmlNodeList xmlNodeList = filedoc["configuration"].GetElementsByTagName("objects");
if (xmlNodeList == null)
{
throw new Exception("configuration file problem");
}
DeserializeObject dObject = new DeserializeObject();
XmlSerializer serializer = new XmlSerializer(dObject.GetType());
var objects = xmlNodeList[0].ChildNodes;
foreach (XmlElement object in objects)
{
var sElement = object.InnerXml;
//string AAA = sElement.ToString();
StringReader SR = new StringReader(/*sElement.InnerXml*//*sElement*/object.OuterXml);
var deserializedObject = serializer.Deserialize(SR);
dObject = (DeserializeObject)serializer.Deserialize(SR);
}
Related
trying to use azure search documents and bind to a specific model
Model
/// <summary>
/// AzureSearchReturnModel
/// </summary>
public class AzureSearchReturnModel
{
/*// <summary>
/// Gets or sets the module identifier.
/// </summary>
/// <value>
/// The module identifier.
/// </value>
public int ModuleId { get; set; }*/
/// <summary>
/// Gets or sets the end item identifier.
/// </summary>
/// <value>
/// The end item identifier.
/// </value>
[SimpleField(IsFilterable = true)]
public int EndItemId { get; set; }
/*// <summary>
/// Gets or sets the end item type identifier.
/// </summary>
/// <value>
/// The end item type identifier.
/// </value>
public int EndItemTypeId { get; set; }
/// <summary>
/// Gets or sets the name of the file.
/// </summary>
/// <value>
/// The name of the file.
/// </value>
public string FileName { get; set; }
/// <summary>
/// Gets or sets the file extension.
/// </summary>
/// <value>
/// The file extension.
/// </value>
public string FileExtension { get; set; }
/// <summary>
/// Gets or sets the name of the module type.
/// </summary>
/// <value>
/// The name of the module type.
/// </value>
public string ModuleTypeName { get; set; }
/// <summary>
/// Gets or sets the size of the file.
/// </summary>
/// <value>
/// The size of the file.
/// </value>
public long FileSize { get; set; }*/
}
Here is a picture of my azure search settings on portal.azure for my index:
Here is the code I'm calling to obtain the results:
/// <summary>
/// Gets the files azure BLOB results from azure search.
/// </summary>
/// <param name="moduleId">The module identifier.</param>
/// <param name="endItemId">The end item identifier.</param>
/// <param name="endItemTypeId">The end item type identifier.</param>
/// <returns></returns>
public IEnumerable<FileManagerFileSystemItem> GetFilesAzureBlobResultsFromAzureSearch(int moduleId, int endItemId, int endItemTypeId)
{
SearchOptions options = new SearchOptions()
{
Filter = string.Format("endItemId eq '82'", endItemId),
/*Filter = string.Format("moduleId eq {0} and endItemId eq {1} and endItemTypeId eq {2}", moduleId.ToString(), endItemId.ToString(), endItemTypeId.ToString()),*/
};
SearchResults<AzureSearchReturnModel> results;
SearchClient searchClient = AzureKeyVaultUtilities.CreateSearchClientForQueries();
options.Select.Add("endItemId");
/*options.Select.Add("moduleId");
options.Select.Add("endItemId");
options.Select.Add("endItemTypeId");
options.Select.Add("moduleType");
options.Select.Add("fileName");
options.Select.Add("fileExtension");
options.Select.Add("metadata_storage_size");*/
results = searchClient.Search<AzureSearchReturnModel>("*", options);
return Enumerable.Empty<FileManagerFileSystemItem>();
}
The code runs without any issues, but my data is not binding to my model.
What am I doing wrong?
It appears the count is right? When I run the query via portal.azure.us it shows me 4 results:
Based on the info you provided, I created an index and write a demo for you.This is my index:
And my code below:
First I upload some docs and then query them with binding to a specific model as you want :
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
namespace AzureSearchTest
{
class Program
{
static void Main(string[] args)
{
var searchServiceName = "";
var cred = "";
var indexName = "";
SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(cred));
ISearchIndexClient indexClient = serviceClient.Indexes.GetClient(indexName);
//UploadDocuments(indexClient);
var results = indexClient.Documents.Search<AzureSearchReturnModel>("*");
Console.WriteLine(results.Results.Count);
}
private static void UploadDocuments(ISearchIndexClient indexClient) {
var AzureSearchReturnModels = new AzureSearchReturnModel[] {
new AzureSearchReturnModel(){
ModuleId = "1" ,
EndItemId = "100",
EndItemTypeId = "200",
FileName= "test file 1",
FileExtension ="txt",
ModuleTypeName = "demo",
FileSize = 20000
},
new AzureSearchReturnModel(){
ModuleId = "2" ,
EndItemId = "100",
EndItemTypeId = "200",
FileName= "test file 2",
FileExtension ="aaa",
ModuleTypeName = "demo",
FileSize = 50000
},
new AzureSearchReturnModel(){
ModuleId = "3" ,
EndItemId = "100",
EndItemTypeId = "200",
FileName= "test file 3",
FileExtension ="bbb",
ModuleTypeName = "demo",
FileSize = 60000
}
};
var batch = IndexBatch.Upload(AzureSearchReturnModels);
indexClient.Documents.Index(batch);
}
}
public class AzureSearchReturnModel
{
[Newtonsoft.Json.JsonProperty(PropertyName = "moduleId")]
public String ModuleId { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "endItemId")]
public String EndItemId { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "endItemTypeId")]
public String EndItemTypeId { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "fileName")]
public string FileName { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "fileExtension")]
public string FileExtension { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "moduleType")]
public string ModuleTypeName { get; set; }
[Newtonsoft.Json.JsonProperty(PropertyName = "metadata_storage_size")]
public long FileSize { get; set; }
}
}
Result:
I am trying to deserialize activity into object type activities according to the RFC (converted XSD to C# class using the XSD in the RFC), but it seems like I'm encountering issues with the activity xml element, since it is containing a inner namespace in the attribute.
XML:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" entity="sip:anon#domain.invalid" xmlns:e="urn:ietf:params:xml:ns:pidf:status:rpid" xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:ce="urn:cisco:params:xml:ns:pidf:rpid" xmlns:sc="urn:ietf:params:xml:ns:pidf:servcaps">
<dm:person>
<status>
<basic>open</basic>
</status>
<e:activities>
</e:activities>
</dm:person>
</presence>
I am deserializing this into a presence object, take the first (presence.Any[0]), and deserialize this into a person object, everything is fine so far. But then I want to take the activity element from person, and deserialize this:
person.Any.SingleOrDefault(x => x.LocalName == "activities")
But now the XML of that object looks like:
<e:activities xmlns:e="urn:ietf:params:xml:ns:pidf:status:rpid">
</e:activities>
And if I try to deserialize this into a activities object as of XSD in RFC3863, I'm ending with the following error message:
Message "<activities xmlns='urn:ietf:params:xml:ns:pidf:status:rpid'> was not expected."
How do I deserialize XmlElements that contains a inner namespace like this??
UPDATE 23-11-17 (Elements which is empty):
XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:pp="urn:ietf:params:xml:ns:pidf:person" xmlns:es="urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status" xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person" entity="sip:Alice#10.24.18.124">
<pp:person>
<status>
<ep:activities>
<ep:away/>
</ep:activities>
</status>
</pp:person>
<note>Unavailable</note>
<tuple id="6001">
<contact priority="1">sip:6001#10.24.18.124</contact>
<status>
<basic>closed</basic>
</status>
</tuple>
</presence>
Problem:
<ep:away xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person" />
Data Entities:
[XmlType(TypeName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public class Activities : activities
{
[XmlElement(Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public ItemsChoiceType State { get; set; }
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:ietf:params:xml:ns:pidf:rpid", IncludeInSchema=false)]
public enum ItemsChoiceType {
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("##any:")]
Item,
/// <remarks/>
appointment,
/// <remarks/>
away,
/// <remarks/>
breakfast,
/// <remarks/>
busy,
/// <remarks/>
dinner,
/// <remarks/>
holiday,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("in-transit")]
intransit,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("looking-for-work")]
lookingforwork,
/// <remarks/>
meal,
/// <remarks/>
meeting,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("on-the-phone")]
onthephone,
/// <remarks/>
other,
/// <remarks/>
performance,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("permanent-absence")]
permanentabsence,
/// <remarks/>
playing,
/// <remarks/>
presentation,
/// <remarks/>
shopping,
/// <remarks/>
sleeping,
/// <remarks/>
spectator,
/// <remarks/>
steering,
/// <remarks/>
travel,
/// <remarks/>
tv,
/// <remarks/>
unknown,
/// <remarks/>
vacation,
/// <remarks/>
working,
/// <remarks/>
worship,
}
You have to declare the namespaces correctly, especially the default namespaces. See working code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string INPUT_FILENAME = #"c:\temp\test.xml";
const string OUTPUT_FILENAME = #"c:\temp\test1.xml";
static void Main(string[] args)
{
Presence outPresence = new Presence()
{
person = new Person()
{
status = new Status()
{
basic = "test"
},
activities = new Activities()
{
}
}
};
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("dm", "urn:ietf:params:xml:ns:pidf:data-model");
xmlNameSpace.Add("e", "urn:ietf:params:xml:ns:pidf:status:rpid");
xmlNameSpace.Add("", "");
XmlSerializer serializer = new XmlSerializer(typeof(Presence), "urn:ietf:params:xml:ns:pidf");
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, settings);
serializer.Serialize(writer, outPresence, xmlNameSpace);
StreamReader reader = new StreamReader(INPUT_FILENAME);
Presence presense = (Presence)serializer.Deserialize(reader);
}
}
[XmlRoot(ElementName = "presence")]
public class Presence
{
[XmlElement(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:data-model")]
public Person person { get; set; }
}
[XmlRoot(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:data-model")]
public class Person
{
[XmlElement(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
public Status status { get; set; }
[XmlElement(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:status:rpid")]
public Activities activities { get; set; }
}
[XmlRoot(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
public class Status
{
[XmlElement("basic")]
public string basic { get; set; }
}
[XmlRoot(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:status:rpid")]
public class Activities
{
}
}
Updated code 11/23/17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string INPUT_FILENAME = #"c:\temp\test.xml";
const string OUTPUT_FILENAME = #"c:\temp\test1.xml";
static void Main(string[] args)
{
Presence outPresence = new Presence()
{
person = new Person()
{
status = new Status()
{
basic = "test",
activities = new Activities()
{
}
},
}
};
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("pp", "urn:ietf:params:xml:ns:pidf:person");
xmlNameSpace.Add("ep", "urn:ietf:params:xml:ns:pidf:rpid:rpid-person");
xmlNameSpace.Add("", "urn:ietf:params:xml:ns:pidf");
XmlSerializer serializer = new XmlSerializer(typeof(Presence), "urn:ietf:params:xml:ns:pidf");
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, settings);
serializer.Serialize(writer, outPresence, xmlNameSpace);
StreamReader reader = new StreamReader(INPUT_FILENAME);
Presence presense = (Presence)serializer.Deserialize(reader);
}
}
[XmlRoot(ElementName = "presence")]
public class Presence
{
[XmlElement(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:person")]
public Person person { get; set; }
}
[XmlRoot(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:person")]
public class Person
{
[XmlElement(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
public Status status { get; set; }
}
[XmlRoot(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
public class Status
{
[XmlElement("basic")]
public string basic { get; set; }
[XmlElement(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public Activities activities { get; set; }
}
[XmlRoot(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public class Activities
{
[XmlElement("away")]
public string away { get; set; }
}
}
I have the following XML I am trying to produce:
<Tags>
<Tag name="Motor" path="_types_" type="UDT_DEF">
<Property name="Value"/>
<Property name="DataType">2</Property>
<Parameters>
</Parameters>
<Tag name="Alm" path="" type="Folder"/>
<Tag name="Sts" path="" type="Folder"/>
<Tag name="Comm" path="Alm" type="OPC">
<Property name="Value"/>
<Property name="DataType">6</Property>
<Property name="OPCServer">Tag Server</Property>
<Property name="OPCItemPath">ns=1;s=Alm.Comm</Property>
<Alarms>
<Alarm name="Alarm">
<Property name="setpointA">1.0</Property>
</Alarm>
</Alarms>
</Tag>
<Tag name="Current" path="Sts" type="OPC">
<Property name="Value"/>
<Property name="DataType">6</Property>
<Property name="OPCServer">Tag Server</Property>
<Property name="OPCItemPath">ns=1;s=Sts.Current</Property>
</Tag>
</Tag>
</Tags>
I setup classes so I have a class for Tags which contain a Tag and I also have class for Alarms, etc. It serialized fine until I got to the tag element "Comm", then it throws an error:
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.Xml.dll
Additional information: There was an error
reflecting type 'TagData.Tags'
How do I serialize my classes into XML when I have multiple element with the same name but different child elements? My thought was to handle the serialization myself but I figured there was a better, easier solution.
Here is my C# classes:
/// <summary>
/// Contains all the tags.
/// </summary>
public class Tags
{
[XmlElement("Tags")]
public List<Tag> ignTagList { get; set; }
}
/// <summary>
/// The tag itself.
/// </summary>
[Serializable()]
public class Tag
{
[XmlAttribute("type")]
public string Type;
[XmlAttribute("path")]
public string Path;
[XmlAttribute("name")]
public string Name;
[XmlElement("Property")]
public List<Property> props { get; set; }
[XmlElement("Tag")]
public List<Folder> folders { get; set; }
[XmlElement("Tag")] // #### ERROR OCCURS HERE. IF I RENAME THIS IT WILL SERIALIZE!! ####
public List<OPCTag> opcTags { get; set; }
public Tag()
{
this.props = new List<Property>();
this.folders = new List<Folder>();
this.opcTags = new List<OPCTag>();
}
public Tag(string Type, string Path, string Name)
{
this.props = new List<Property>();
this.folders = new List<Folder>();
this.opcTags = new List<OPCTag>();
this.Type = Type;
this.Path = Path;
this.Name = Name;
}
}
/// <summary>
/// Property data structure.
/// </summary>
[Serializable()]
public class Property
{
[XmlAttribute("name")]
public string Name;
[XmlText]
public string DataTypeValue;
public Property()
{
}
public Property(string Name, string DataTypeValue)
{
this.Name = Name;
this.DataTypeValue = DataTypeValue;
}
}
/// <summary>
/// Folder data structure.
/// </summary>
[Serializable()]
public class Folder
{
[XmlAttribute("type")]
public string Type;
[XmlAttribute("path")]
public string Path;
[XmlAttribute("name")]
public string Name;
public Folder()
{
}
public Folder(string Type, string Path, string Name)
{
this.Type = Type;
this.Path = Path;
this.Name = Name;
}
public Folder(string Path, string Name)
{
this.Type = "Folder";
this.Path = Path;
this.Name = Name;
}
}
/// <summary>
/// OPC tag data structure.
/// </summary>
[Serializable()]
public class OPCTag
{
[XmlAttribute("type")]
public string Type;
[XmlAttribute("path")]
public string Path;
[XmlAttribute("name")]
public string Name;
[XmlIgnore]
public IgnDataType DataType;
[XmlElement("Property")]
public List<Property> props { get; set; }
public OPCTag()
{
this.props = new List<Property>();
}
public OPCTag(string Type, string Path, string Name)
{
this.Type = Type;
this.Path = Path;
this.Name = Name;
this.props = new List<Property>();
}
public OPCTag(string Path, string Name, UDTDataType DataType)
{
this.Type = "OPC";
this.Path = Path;
this.Name = Name;
this.props = new List<Property>();
this.props.Add(new Property("Value", ""));
this.props.Add(new Property("DataType", ((int)DataType).ToString()));
}
}
I have an ModelChangeInfo object that define two enums : ModelType and ChangeType. When i deserialize ModelChangeInfo object, only ChangeTypevalue can deserialize, ModelType cannot, ModelType value is null.
This is my code
public class ModelChangeInfo
{
public ModelChangeInfo(Guid id, ModelType? modelType, ChangeType? changeType, ParentInfo parentInfo = null)
{
Id = id;
ElementType = modelType;
ChangeType = changeType;
ParentInfo = parentInfo;
}
/// <summary>
/// Gets model's id
/// </summary>
public Guid Id { get; private set; }
/// <summary>
/// Gets model's element type
/// </summary>
public ModelType? ElementType { get; private set; }
/// <summary>
/// Gets change type
/// </summary>
public ChangeType? ChangeType { get; private set; }
/// <summary>
/// Gets parent information
/// </summary>
public ParentInfo ParentInfo { get; private set; }
public override string ToString()
{
return string.Format("ElementType {0}. ChangeType {1}. Parent ElementType {2}", ElementType, ChangeType, ParentInfo.ElementType);
}
}
public class ParentInfo
{
public ParentInfo(Guid id, ModelType? modelType)
{
Id = id;
ElementType = modelType;
}
/// <summary>
/// Gets model's id
/// </summary>
public Guid Id { get; private set; }
/// <summary>
/// Gets model's element type
/// </summary>
public ModelType? ElementType { get; private set; }
}
[JsonConverter(typeof(StringEnumConverter))]
public enum ModelType
{
Network,
TradingPartner,
Transaction,
Task,
File
}
[JsonConverter(typeof(StringEnumConverter))]
public enum ChangeType
{
Add,
Update,
Delete
}
public class JsonDemo
{
static void Main(string[] args)
{
ParentInfo parentInfo = new ParentInfo(Guid.NewGuid(), ModelType.TradingPartner);
ModelChangeInfo modelChangeInfo = new ModelChangeInfo(Guid.NewGuid(), ModelType.File, ChangeType.Update, parentInfo);
JsonSerializer serializer = new JsonSerializer();
using (StreamWriter sw = new StreamWriter(#"C:\json.txt"))
{
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, modelChangeInfo);
}
}
using (StreamReader sr = new StreamReader(#"D:\json.txt"))
{
using (JsonReader reader = new JsonTextReader(sr))
{
ModelChangeInfo temp = serializer.Deserialize<ModelChangeInfo>(reader);
Console.WriteLine(temp);
}
}
Console.Read();
}
}
I have a string data get from service Location Xml
I want to read response text and return ObservableCollection
public void SearchLocation(string address)
{
var webclient = new WebClient();
if (address != "")
{
string url =
string.Format(
#"http://dev.virtualearth.net/REST/v1/Locations?countryRegion=Vietnam&adminDistrict=Ha Noi&locality={0}&o=xml&key={1}",
address, BingMapKey);
webclient.DownloadStringAsync(new Uri(url));
webclient.DownloadStringCompleted += WebclientOnDownloadStringCompleted;
}
}
private void WebclientOnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string data = e.Result;
ReadXml(data);
}
private void ReadXml(string data)
{
_locations.Clear();
XDocument document = XDocument.Parse(data);
var locations = from loca in document.Descendants("Location")
select
new Location(loca.Element("Name").Value,
loca.Element("Point").Element("Latitude").Value,"1",
"1", "1", "1", "1");
_locations = (ObservableCollection<Location>) locations;
}
}
Class Location:
public class Location
{
/// <summary>
/// Tên địa điểm
/// </summary>
public string Name { get; set; }
/// <summary>
/// Vĩ độ
/// </summary>
public double Latitude { get; set; }
/// <summary>
/// Kinh độ
/// </summary>
public double Longitute { get; set; }
/// <summary>
/// Vĩ độ Nam
/// </summary>
public double SouthLatitude { get; set; }
/// <summary>
/// Kinh độ Tây
/// </summary>
public double WestLongtitue { get; set; }
/// <summary>
/// Vĩ độ Bắc
/// </summary>
public double NorthLatitude { get; set; }
/// <summary>
/// Kinh độ Tây
/// </summary>
public double EastLongitude { get; set; }
/// <summary>
/// Khởi tạo Location
/// </summary>
/// <param name="name">tên địa điểm</param>
/// <param name="latitue">vĩ độ</param>
/// <param name="longitude">kinh độ</param>
/// <param name="southLatitude">vĩ độ nam</param>
/// <param name="westLongitude">kinh độ tây</param>
/// <param name="northLatitude">vĩ độ bắc</param>
/// <param name="eastLongitude">kinh độ đông</param>
public Location(string name, string latitue, string longitude, string southLatitude, string westLongitude,
string northLatitude, string eastLongitude)
{
Name = name;
Latitude = Convert.ToDouble(latitue);
Longitute = Convert.ToDouble(longitude);
SouthLatitude = Convert.ToDouble(southLatitude);
NorthLatitude = Convert.ToDouble(northLatitude);
WestLongtitue = Convert.ToDouble(westLongitude);
EastLongitude = Convert.ToDouble(eastLongitude);
}
}
I read and _location return null, where are errors?
You can cast IEnumerable<Location> which is a result of LINQ to XML query to ObservableCollection<Location> directly.
_locations = (ObservableCollection<Location>) locations;
Just add all elements from query result collection into existing ObservableCollection:
foreach(var location in locations)
_locations.Add(location);
Update
There is also namespace problem in your code. Try that one:
XDocument document = XDocument.Parse(data);
var ns = XNamespace.Get("http://schemas.microsoft.com/search/local/ws/rest/v1");
var locations = from loca in document.Descendants(ns + "Location")
select
new Location(loca.Element(ns + "Name").Value,
loca.Element(ns + "Point").Element(ns + "Latitude").Value, "1",
"1", "1", "1", "1");