2011-03-23 85 views
1

我成立了一个WCF Web服务中的Visual Web Developer 2010速成使用4.0框架,并将其转换为RESTful服务using this tutorial如何在RESTful .NET WCF Web服务中返回XML?

我可以修改它符合我的心意,接受URL参数,就像这样:

namespace RestServicePublishing 
{ 
[ServiceContract] 
public interface IRestService 
{ 
    [OperationContract(Name="GetXML")] 
    [WebGet(UriTemplate = "/{param1}/{param2}")] 
    XmlDocument GetXML(string param1, string param2); 
} 
} 

我遇到的问题是试图返回这样的一个XML文档时,我得到一个“类型‘System.Xml.XmlDocument’无法序列”错误:

namespace RestServicePublishing 
{ 
public class RestService : IRestService 
    { 

    public XmlDocument GetXML(string param1, string param2) 
    { 

     //I am not using the parameters currently, I would just like to see if 
     //i can return XML first with this simple example: 

     StringBuilder sb = new StringBuilder(); 
     System.Xml.XmlWriter writer = XmlWriter.Create(sb); 
     writer.WriteStartDocument(); 
     writer.WriteStartElement("People"); 
     writer.WriteStartElement("Person"); 
     writer.WriteAttributeString("Name", "Nick"); 
     writer.WriteEndElement(); 
     writer.WriteStartElement("Person"); 
     writer.WriteStartAttribute("Name"); 
     writer.WriteValue("Nick"); 
     writer.WriteEndAttribute(); 
     writer.WriteEndElement(); 
     writer.WriteEndElement(); 
     writer.WriteEndDocument(); 
     writer.Flush(); 

     XmlDocument xmlDocument = new Xml.XmlDocument(); 
     xmlDocument.LoadXml(sb.ToString()); 
     return xmlDocument; 
    } 

} 
} 

我知道re必须是设置XML文档并将其返回的更好方法..非常感谢任何帮助!

预先感谢您!

回答

4

是的 - 好.... WCF的模型说,你不应该尝试返回一个XmlDocument本身。相反,您将返回在您的编程环境中定义的自定义类型。该类型需要标记以指定如何将其序列化为XML。然后,当该方法返回自定义类型时,WCF会隐式地将其序列化为XML文档。

我想你想回到什么是这样的:

<People> 
    <Person Name="Nick"/> 
    <Person Name="Bonnie"/> 
</People> 

但DataContractSerializer的不喜欢发出属性。所以在生成XML Web服务的正常方式使用WCF,你反而会得到这样的:

<People> 
    <Person><Name>Nick</Name></Person> 
    <Person><Name>Bonnie</Name></Person> 
</People> 

为了做到这一点,写你的C#代码:

namespace RestServicePublishing 
{ 
    [ServiceContract] 
    public interface IRestService 
    { 
     [OperationContract(Name="GetXML")] 
     [WebGet(UriTemplate = "/{param1}/{param2}")] 
     List<Person> GetXML(string param1, string param2); 
    } 
} 

那么类型应该看起来像这样:

[DataContract] 
public class Person 
{ 
    [DataMember] 
    public string Name { get; set; } 
} 

[CollectionDataContract(Name = "People")] 
public class People : List<Person> 
{ 
} 
+0

对不起,听起来像这样一个noob,但我该如何处理你给的类型的例子?我创建了一个名为'Person'的新类,并放入该代码中,但是从那里我对接下来要做的事情有点困惑。再次感谢您的回应! – AngeloS 2011-03-23 23:58:59

+0

我想通了..创建两个类:1.Person和2.People并在上面的代码。然后在GetXML()方法中,让它返回列表(同时,更改服务合同中的返回类型)。最后,创建一个新的人员列表' ppl = new List ();',然后实例化一个新的Person,如'Person prsn = new Person();'并为它添加一个名称,然后通过ppl.Add(new People {prsn})将该Person添加到人员列表中; ...最后返回'返回新列表(ppl); – AngeloS 2011-03-24 00:35:29

+2

我觉得困惑是因为你不需要GetXML方法。如果你的服务只是返回Person(或者列表),那么WCF会为你做XML的东西。 :) – Tridus 2011-03-24 01:44:47

2

将其作为字符串返回,然后将该字符串加载到另一端的XmlDocument

Is there an issue sending XML via WCF?

或最好,创建一个DataContract类,模拟代码中的XML结构,然后WCF会把它变成XML为您服务。

+0

我去'发回它作为一个字符串'的方法..谢谢! – AngeloS 2011-03-23 23:39:57

+0

在字符串中返回XML通常是一个糟糕的主意。最好是返回一个自定义类型,以您喜欢的形式为您序列化。 – Cheeso 2011-03-23 23:48:09

+0

@Cheeso你是downvoter?请重新阅读,我提供了您的解决方案作为替代。我不认为这是一个“坏主意”,你不知道什么系统连接到这个服务,或者构建响应XML是多么容易。在这种情况下恕我直言,downvote不保证。 – 2011-03-24 08:43:24