десериализация xml из ответа azure
Я хочу десериализовать данные и поместить их в универсальный класс из ответа от Azure.
<ServiceResources xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/windowsazure">
<ServiceResource>
<Name>Airport1</Name>
<Type>Microsoft.SqlAzure.FirewallRule</Type>
<State>Normal</State>
<SelfLink>https://management.core.windows.net:xxx/xxx/services/sqlservers/servers/xxx/firewallrules/Airport1</SelfLink>
<ParentLink>https://management.core.windows.net:xxxx/services/sqlservers/servers/xxx</ParentLink>
<StartIPAddress>000.000.000.000</StartIPAddress>
<EndIPAddress>2000.000.000.000</EndIPAddress>
</ServiceResource>
Есть несколько объектов, которые я должен десериализовать в свой класс.
[Serializable, XmlRoot(ElementName = "ServiceResource", Namespace = "http://schemas.microsoft.com/windowsazure/")]
public class ServiceResource
{
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Type")]
public string Type { get; set; }
[XmlElement("State")]
public string State { get; set; }
[XmlElement("SelfLink")]
public string SelfLink { get; set; }
[XmlElement("ParentLink")]
public string ParentLink { get; set; }
[XmlElement("StartIPAddress")]
public string StartIPAddress { get; set; }
[XmlElement("EndIPAddress")]
public string EndIPAddress { get; set; }
}
Я попробовал несколько различных предприятий в этом и не могу его прижать. Я использовал xmlSerializer
, но ударил блоки на этом.
using (var responseStreamReader = new StreamReader(webResponse.GetResponseStream()))
{
XmlSerializer serializer = new XmlSerializer(typeof(ServiceResource));
ServiceResource deserialized = (ServiceResource)serializer.Deserialize(responseStreamReader);
}
Любая помощь будет с благодарностью принято.
2 ответа:
Ответ
Api REST Azure возвращает список
ServiceResource
в XML. Поэтому вам нужно инкапсулировать это в класс. Вот вам пример.С этими двумя классами теперь можно сделать следующее.[XmlRoot( ElementName = "ServiceResources", Namespace = "http://schemas.microsoft.com/windowsazure")] public class ServiceResources { public ServiceResources() { Items = new List<ServiceResource>(); } [XmlElement("ServiceResource")] public List<ServiceResource> Items { get; set; } } public class ServiceResource { [XmlElement("Name")] public string Name { get; set; } [XmlElement("Type")] public string Type { get; set; } [XmlElement("State")] public string State { get; set; } [XmlElement("SelfLink")] public string SelfLink { get; set; } [XmlElement("ParentLink")] public string ParentLink { get; set; } [XmlElement("StartIPAddress")] public string StartIPAddress { get; set; } [XmlElement("EndIPAddress")] public string EndIPAddress { get; set; } }
var response = request.GetResponse(); var message = string.Empty; using (var responseStreamReader = new StreamReader(response.GetResponseStream())) { message = responseStreamReader.ReadToEnd(); } var textReader = new StringReader(message); var serializer = new XmlSerializer(typeof(ServiceResources)); var serviceResources = serializer.Deserialize(textReader) as ServiceResources;
Демонстрационное Консольное Приложение
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Xml; using System.Xml.Serialization; namespace DeserializeAzureXmlResponse { class Program { private static string certificateThumbprint = "19DAED4D4ABBE0D400DC33A6D99D00D7BBB24472"; private static string subscriptionId = "14929cfc-3501-48cf-a5c9-b24a7daaf694"; static string sqlServerName = "mvp2015"; static string managementUri = "https://management.core.windows.net"; static string sqlServerApi = "services/sqlservers/servers"; static string firewallRules = "firewallrules"; static void Main(string[] args) { var restUri = CreateRestUri(); var clientCert = GetX509FromPersonalStore(); var request = (HttpWebRequest)HttpWebRequest.Create(restUri); request.Headers.Add("x-ms-version", "2012-03-01"); request.ClientCertificates.Add(clientCert); var response = request.GetResponse(); var message = string.Empty; using (var responseStreamReader = new StreamReader(response.GetResponseStream())) { message = responseStreamReader.ReadToEnd(); } var textReader = new StringReader(message); var serializer = new XmlSerializer(typeof(ServiceResources)); var serviceResources = serializer.Deserialize(textReader) as ServiceResources; foreach (var sr in serviceResources.Items) { Console.WriteLine("Name".PadRight(20) + sr.Name); Console.WriteLine("Type".PadRight(20) + sr.Type); Console.WriteLine("State".PadRight(20) + sr.State); Console.WriteLine("SelfLink".PadRight(20) + sr.SelfLink); Console.WriteLine("ParentLink".PadRight(20) + sr.ParentLink); Console.WriteLine("StartIP".PadRight(20) + sr.StartIPAddress); Console.WriteLine("EndIP".PadRight(20) + sr.EndIPAddress); Console.WriteLine("+++++++++++"); } Console.ReadLine(); } static Uri CreateRestUri() { // https://management.core.windows.net/{subscriptionID}/services/sqlservers/servers/{server}/firewallrules/ var builder = new StringBuilder(); builder.Append(managementUri + "/"); builder.Append(subscriptionId + "/"); builder.Append(sqlServerApi + "/"); builder.Append(sqlServerName + "/"); builder.Append(firewallRules + "/"); var uri = new Uri(builder.ToString()); return uri; } static X509Certificate GetX509FromPersonalStore() { // To view the personal store, press `Win + R` and then type `certmgr.msc` var store = new X509Store(StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, true); var certificate = certificates[0]; store.Close(); return certificate; } } [XmlRoot( ElementName = "ServiceResources", Namespace = "http://schemas.microsoft.com/windowsazure")] public class ServiceResources { public ServiceResources() { Items = new List<ServiceResource>(); } [XmlElement("ServiceResource")] public List<ServiceResource> Items { get; set; } } public class ServiceResource { [XmlElement("Name")] public string Name { get; set; } [XmlElement("Type")] public string Type { get; set; } [XmlElement("State")] public string State { get; set; } [XmlElement("SelfLink")] public string SelfLink { get; set; } [XmlElement("ParentLink")] public string ParentLink { get; set; } [XmlElement("StartIPAddress")] public string StartIPAddress { get; set; } [XmlElement("EndIPAddress")] public string EndIPAddress { get; set; } } }
Вывод
Name My-House Type Microsoft.SqlAzure.FirewallRule State Normal SelfLink https://management.core.windows.net/14929cfc-35 ParentLink https://management.core.windows.net/14929cfc-35 StartIP 123.435.234.643 EndIP 123.435.234.643 +++++++++++ Name AllowAllWindowsAzureIps Type Microsoft.SqlAzure.FirewallRule State Normal SelfLink https://management.core.windows.net/14929cfc-35 ParentLink https://management.core.windows.net/14929cfc-35 StartIP 0.0.0.0 EndIP 0.0.0.0 +++++++++++
См. Также
Я предполагаю, что вы пытаетесь десериализовать весь граф объектов. Данный xml имеет корневой узел
ServiceResources
, который содержитServiceResource
. У вас есть два варианта: вы можете скопировать весь xml в классы и десриализовать; или просто получить внутренний узелServiceResource
и десериализовать эту часть.Если вы используете первый вариант, то вам нужно будет хранить ServiceResource внутри другого класса, который имеет свойство сопоставленных коллекций с именем XmlElement, установленным в "ServiceResource", например:
[XmlType(Namespace="http://schemas.microsoft.com/windowsazure")] [XmlRoot(Namespace="http://schemas.microsoft.com/windowsazure")] public class ServiceResource { public string Name { get; set; } public string Type { get; set; } public string State { get; set; } public string SelfLink { get; set; } public string ParentLink { get; set; } public string StartIPAddress { get; set; } public string EndIPAddress { get; set; } } [XmlType(Namespace="http://schemas.microsoft.com/windowsazure")] [XmlRoot(Namespace="http://schemas.microsoft.com/windowsazure")] public class ServiceResources { [XmlElement("ServiceResource")] public List<ServiceResource> ServiceResource { get; set; } }
С этим вы должна быть возможность десериализоваться напрямую. Класс Container имеет коллекции, сопоставленные элементу ServiceResource, который будет загружать все узлы для ресурса service. Примечание: целевой тип десериализации теперь "ServiceResources", а не внутренний тип "ServiceResource"
using (var responseStreamReader = new StreamReader(webResponse.GetResponseStream())) { XmlSerializer serializer = new XmlSerializer(typeof(ServiceResources)); ServiceResources deserialized = (ServiceResources)serializer.Deserialize(responseStreamReader); //you can access each item in loop foreach(var res in deserialized.ServiceResource) { //access items e.g. var name = res.Name; } }