如何使用c#将XML数据转换为类文件(反序列化对象)

时间:2011-06-09 20:10:02

标签: xml wcf xml-serialization

我使用wcf.My创建了一个WCF Rest API服务。服务方法返回多个数据类型,一些方法返回类的对象或类,bool,int或集合类型的集合。所以我计划在所有方法中返回相同的响应。我创建一个新类如下:

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

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

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

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

}

在ServiceResponse类中,我声明了一个Object Type属性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类对象(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<BlogEntryDTO> blogEntries=(Collection<BlogEntryDTO>) ResponseData;

我该怎么做?

2 个答案:

答案 0 :(得分:2)

我认为这里不需要DataContract和DataMember属性。您应该使用WCF阅读this article about using the XmlSerializer

要反序列化您的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);
    }

然后用户对象应该是正确的类型。

答案 1 :(得分:0)

这样的东西?

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