2015-09-14 3 views
3

Я ищу десериализацию данных и поместите их в общий класс от response from Azure.deserialize xml from azure response

<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); 

} 

Любая помощь была бы с благодарностью принята.

+0

Где вызов метода Deserialize? –

+0

изменил код для отображения – scottsanpedro

ответ

2

Ответ

The Azure REST Апи возвращается список 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; 

Демонстрация консоли App

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 
+++++++++++ 

Смотрите также

Is it possible to deserialize XML into List<T>?

List Firewall Rules

+0

получение не ожидалось. – scottsanpedro

+0

Исправлено это, чтобы избежать этого исключения. –

+1

Большое спасибо. Действительно полезно. Выберете резервную копию, как только сможете, и подтвердите. – scottsanpedro

3

Я предполагаю, что вы пытаетесь десериализировать весь граф объектов. У данного xml есть корневой узел ServiceResources который содержит ServiceResource. У вас есть два варианта: вы можете имитировать весь xml в классы и desrialize; или просто получить внутренний узел 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, который загружает все узлы ресурса службы. Примечание: целевой тип десериализации теперь «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; 
    } 
} 
+0

Первый вариант вызывает следующую ошибку: '{" не ожидалось. "}' –

+1

Исправлено. Пространство имен отсутствовало, украсить два класса: [XmlType (Namespace = "http://schemas.microsoft.com/windowsazure ")] и [XmlRoot (Namespace =" http://schemas.microsoft.com/windowsazure ")] – loopedcode

+1

Спасибо за вашу помощь. Это сработало отлично. Было бы полезно принять оба. – scottsanpedro