WCF:如何为极其简单的响应定义DataContract类?需要反序列化根元素的Text

时间:2011-06-18 21:49:34

标签: wcf serialization

我想调用Sql Azure的REST API来创建SQL Azure服务器。该方法记录在此处:http://msdn.microsoft.com/en-us/library/gg715274.aspx 我遇到了问题。这种方法的反应非常简单: <?xml version="1.0" encoding="utf-8"?><ServerName xmlns="http://schemas.microsoft.com/sqlazure/2010/12/">zpc0fbxur0</ServerName>

如何为此响应定义DataContract类? 如果响应是这样的: <?xml version="1.0" encoding="utf-8"?> <ServerName xmlns="http://schemas.microsoft.com/sqlazure/2010/12/"><Name>zpc0fbxur0</Name></ServerName> 以下课程将起作用:

`

    [DataContract(Namespace=SqlAzureConstants.ManagementNS, Name="ServerName")]
    public class ServerName : IExtensibleDataObject
    {
        [DataMember()]
        public string Name
        {
            get;
            set;
        }

        public ExtensionDataObject ExtensionData
        {
            get;
            set;
        }
    }

`

但是我需要指定该属性应该映射到根元素的文本。任何想法如何做到这一点?

1 个答案:

答案 0 :(得分:1)

默认情况下创建的DataContractSerializer无法反序列化该XML - 但如果使用设置rootNamerootNamespace参数的构造函数,则可以完成。

另一种方法是使用XmlSerializer,您可以直接使用它。

下面的代码显示了这两个选项,以及使用XmlSerializer类型的WebChannelFactory实现。

public class StackOverflow_6399085
{
    [XmlRoot(ElementName = "ServerName", Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]
    public class ServerName
    {
        [XmlText]
        public string Name { get; set; }

        public override string ToString()
        {
            return string.Format("ServerName[Name={0}]", this.Name);
        }
    }

    const string XML = "<?xml version=\"1.0\" encoding=\"utf-8\"?><ServerName xmlns=\"http://schemas.microsoft.com/sqlazure/2010/12/\">zpc0fbxur0</ServerName>";

    static void RunWithXmlSerializer()
    {
        XmlSerializer xs = new XmlSerializer(typeof(ServerName));
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
        ServerName obj = (ServerName)xs.Deserialize(ms);
        Console.WriteLine("Using XML serializer: {0}", obj);
    }

    static void RunWithDataContractSerializer()
    {
        DataContractSerializer dcs = new DataContractSerializer(typeof(string), "ServerName", "http://schemas.microsoft.com/sqlazure/2010/12/");
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
        string name = (string)dcs.ReadObject(ms);
        Console.WriteLine("Using DataContractSerializer (different name): {0}", name);
    }

    [ServiceContract(Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]
    public class MockSqlAzureRestService
    {
        [WebGet]
        public Stream GetServerName()
        {
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
            WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
            return ms;
        }
    }

    [ServiceContract(Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]
    public interface IServerNameClient
    {
        [WebGet(BodyStyle = WebMessageBodyStyle.Bare)]
        [XmlSerializerFormat]
        ServerName GetServerName();
    }

    static void RunWithWCFRestClient()
    {
        // Setting up the mock service
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        WebServiceHost host = new WebServiceHost(typeof(MockSqlAzureRestService), new Uri(baseAddress));
        host.Open();

        WebChannelFactory<IServerNameClient> factory = new WebChannelFactory<IServerNameClient>(new Uri(baseAddress));
        IServerNameClient proxy = factory.CreateChannel();
        var name = proxy.GetServerName();
        Console.WriteLine("Using WCF REST client: {0}", name);
    }

    public static void Test()
    {
        RunWithXmlSerializer();
        RunWithDataContractSerializer();
        RunWithWCFRestClient();
    }
}