2

我正在使用带有框架 4.0 的 WCF restful web 服务。我想将数据表序列化为 XML 并返回生成的 XML。我有这个工作,但我不禁觉得有更好的方法。

我最初开始做以下事情:

[WebGet(UriTemplate = "")]
public DataTable helloWorld()
{
    using (DataTable dt = new DataTable("Test"))
    {
        dt.Columns.Add("Message");
        dt.Rows.Add(dt.NewRow());
        dt.Rows[0]["Message"] = "Hello World";

        return dt;
    }
}

这给了我以下不良结果:

<DataTable xmlns="http://schemas.datacontract.org/2004/07/System.Data">
  <xs:schema id="NewDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns=""     xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="Test" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Test">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Message" type="xs:string" minOccurs="0"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <DocumentElement xmlns="">
      <Test diffgr:id="Test1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
        <Message>Hello World</Message>
      </Test>
    </DocumentElement>
  </diffgr:diffgram>
</DataTable>

经过一番修改后,我想出了以下代码,这有点笨拙。有没有更好的办法?为什么我不能处理内存流?我有内存泄漏吗?

[WebGet(UriTemplate = "")]
public Stream helloWorld()
{
    WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";

    using (DataTable dt = new DataTable("Test"))
    {
        dt.Columns.Add("Message");
        dt.Rows.Add(dt.NewRow());
        dt.Rows[0]["Message"] = "Hello World";

        using (StringWriter sw = new StringWriter())
        {
            dt.WriteXml(sw, System.Data.XmlWriteMode.IgnoreSchema, false);

            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sw.ToString()));
            return ms;

            //this fails for some reason
            //using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sw.ToString())))
            //    return ms;
        }
    }
}

这段代码给了我想要的结果(我对根标签并不挑剔):

<DocumentElement>
  <Test>
    <Message>Hello World</Message>
  </Test>
</DocumentElement>
4

2 回答 2

1

我建议使用WCF 数据服务来执行此操作。它们实现了OData协议,这意味着它们旨在以一致且可移植的方式公开数据。可以对 JSON 或 XML 进行序列化。

样品:

  1. 初级水平
  2. 更全面的解释和示例。
于 2013-05-11T20:02:52.897 回答
0

我建议使用 DataContract 进行序列化:

这是一个关于如何做到这一点的好教程:http: //www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide

您创建一个合约接口,在其中定义所有必要的方法。

在你的情况下是这样的:

namespace MyProject.HelloWorld {
    [ServiceContract]
    public interface IHelloWorld {
        [OperationContract]
        [WebGet(UriTemplate="", ResponeFormat=WebMessageFormat.Xml)]
        HelloWorldResult helloWorld();
    }

    [DataContract()]
    public class HelloWorldResult {
        [DataMember]
        public String Message {get; set;}
    }
}

只需在 Service.svc 中实现接口 IHelloWorld 并返回 HelloWorldResult 类的新实例:

public HelloWorldResult helloWorld() {
   return new HelloWorldResult() {
       Message = "Hello World!"
   };
}

但是您必须告诉端点使用 IHelloWorld 服务合同作为合同(参见教程: http: //www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide --> 步骤 6)

希望这可以帮助

干杯

于 2013-05-11T19:55:52.693 回答