Как преобразовать данные XML в файл класса с помощью c # (десериализация объектов) - PullRequest
1 голос
/ 10 июня 2011

Я создал службу API отдыха WCF с использованием методов службы wcf.My, возвращающих несколько типов данных. Некоторые методы возвращают объект класса или коллекции типа class, bool, int или collection. поэтому я планировал вернуть один и тот же Response во всех методах для этого. Создайте новый класс следующим образом:

    [DataContract(Namespace = "")]
public class ServiceResponse
{

 [DataMember]
  public bool IsError
    { get; set; }

[DataMember]
public string ResponseMessage
{ get; set; }

[DataMember]
public Object ResponseData
{ get; set; }       

}

В классе ServiceResponse я объявил свойство типа объекта ResponseData, и мой метод all имеет тип возврата ServiceResponse.see ниже кода:

public ServiceResponse GetUser(int userID)
{

    User user = getUser(userID); get user data from database

    ServiceResponse response=new ServiceResponse();
    var response = new ServiceResponse
                       {
                           IsError = false,
                           ResponseMessage = string.Empty,
                           ResponseData = user; // Setting Result Data here
                       };
    return response;

}

после вызова службы я могу получить ответ и десериализовать его для объекта класса My return type (ServiceResponse)

var streamReader = new StreamReader(response.GetResponseStream());
var xSerializer = new XmlSerializer(typeof(ServiceResponse ));

var result = (ServiceResponse)xSerializer.Deserialize(streamReader);

XML, который я получаю от сервиса, выглядит так:

<RestResponse>
<IsError>false</IsError>
<ResponseData i:type="ArrayOfBlogEntryDTO">
    <BlogEntryDTO>
        <Active>0</Active>            
        <BlogEntryID>36</BlogEntryID>            
        <UserID>1</UserID>
        <UserName>admin</UserName>            
        <Views>12</Views>            
    </BlogEntryDTO>
    <BlogEntryDTO>
        <Active>0</Active>            
        <BlogEntryID>36</BlogEntryID>            
        <UserID>1</UserID>
        <UserName>admin</UserName>            
        <Views>12</Views>            
    </BlogEntryDTO>
</ResponseData>
<ResponseMessage></ResponseMessage>

так как в свойстве ResponseData у меня есть массив объекта класса (Collection of class class), я хочу получить его в коллекции или объекте пользовательского класса.

похож на:

Collection<BlogEntryDTO> blogEntries=(Collection<BlogEntryDTO>) ResponseData;

Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 10 июня 2011

Я не думаю, что атрибуты DataContract и DataMember необходимы здесь. Вам следует прочитать эту статью об использовании XmlSerializer с WCF.

Чтобы десериализовать ваш объект ResponseData, вы должны сначала знать, к какому типу класса его десериализовать. DataContractSerializer добавляет разметку к XML, чтобы он знал тип. Я не верю, что XmlSerializer делает это, поэтому вам нужно будет указать дополнительное имя типа в качестве другого свойства в вашем классе ServiceResponse. Это также означает, что первый проход не сможет правильно десериализоваться, поэтому вам, вероятно, потребуется сериализовать вручную на сервере и отправить его в виде строки, а затем снова десериализовать вручную на клиенте, чтобы преобразовать его в ваш пользовательский объект.

Вам нужно будет переключить ваши ResponseData на строковый объект, а base64 закодировать сериализованный результат (или что-то подобное). И тогда вам понадобится дополнительное строковое свойство ResponseType.

Итак, на сервере вы бы сделали это:

using (var ms = new MemoryStream())
{
    xmlSerializer.Serialize(ms, user);
    response.ResponseData = Convert.ToBase64String(ms.ToArray());
    response.ResponseType = user.GetType().FullName;
}

Затем на клиенте вы бы сделали что-то вроде этого:

    var responseData = Convert.FromBase64String(result.ResponseData);
    var responseType = Type.GetType(result.ResponseType);
    var responseSerializer = new XmlSerializer(responseType);
    using (var ms = new MemoryStream(responseData))
    {
        var user = responseSerializer.Deserialize(ms);
    }

Тогда пользовательский объект должен быть правильного типа.

0 голосов
/ 10 июня 2011

Как то так?

[DataContract(Namespace = "")]
public class ServiceResponse<TObject>
{
    [DataMember]
    public bool IsError { get; set; }

    [DataMember]
    public string ResponseMessage { get; set; }

    [DataMember]
    public TObject ResponseData { get; set; }
}

А потом десериализовать:

var streamReader = new StreamReader(response.GetResponseStream());
var xSerializer = new XmlSerializer(typeof(ServiceResponse<IEnumerable<BlogEntryDTO>>));
var result = (ServiceResponse<IEnumerable<BlogEntryDTO>>)xSerializer.Deserialize(streamReader);
...