C# 如何使用 WCF 服务生成 XML 输出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13345557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to produce XML output using WCF service?
提问by
I've set up the following interface.
我已经设置了以下界面。
[ServiceContract]
public interface IService1
{
[OperationContract]
String Ping();
}
Its implementation is as follows.
其实现如下。
public class Service1 : IService1
{
public string Ping(){ return "Pong"; }
}
According to the testing application in VS it's working properly when invoked. My problem is that I'd like the text to appear on the screen when I type http://localhost:12345/Service1.svc(or maybe Service1.svc?Pingor Service.svc/Ping). Is it totally off or am I barking up the right tree?
根据 VS 中的测试应用程序,它在调用时工作正常。我的问题是,当我输入http://localhost:12345/Service1.svc(或者Service1.svc?Ping或Service.svc/Ping)时,我希望文本出现在屏幕上。是完全关闭还是我在正确的树上吠叫?
Of course, "Pong" will eventually be an XML strucure.
当然,“ Pong”最终将是一个 XML 结构。
EDIT
编辑
The set-up presented in the reply by @carlosfigueira below gives a good structure to a suggestion for a solution but unfortunately leads on my machine to an error message when run using F5. It seems that metadata is required and that the same goes for endpoints.
下面@carlosfigueira 的回复中提供的设置为解决方案的建议提供了一个很好的结构,但不幸的是,当使用 F5 运行时,我的机器上会出现错误消息。似乎需要元数据,端点也是如此。
采纳答案by Konrad Viltersten
I finally got totally PO and went off to business full contact. This is what I've produced - it works on my machine and I hope it's not a local phenomenon. :)
我终于得到了完全的 PO 并开始完全联系业务。这是我制作的 - 它在我的机器上工作,我希望这不是本地现象。:)
IRestService.cs- the declaration, what your code promises to a contacting client
IRestService.cs- 声明,您的代码向联系客户承诺的内容
[ServiceContract]
public interface IRestService
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "xml/{id}")]
String XmlData(String id);
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "json/{id}")]
String JsonData(String id);
}
RestService.svc.cs- the implementation, what your code actually does to the client
RestService.svc.cs- 实现,你的代码实际上对客户端做了什么
public class RestService : IRestService
{
public String XmlData(String id)
{
return "Requested XML of id " + id;
}
public String JsonData(String id)
{
return "Requested JSON of id " + id;
}
}
Web.config- the configuration, what your code is handled as on the way to the client
Web.config- 配置,您的代码在到达客户端的途中处理的内容
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
...
</services>
<behaviors>
</behaviors>
</system.serviceModel>
</configuration>
services- contents of the tag describing the service's nature
services- 描述服务性质的标签内容
<service name="DemoRest.RestService"
behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="webHttpBinding"
contract="DemoRest.IRestService"
behaviorConfiguration="web"></endpoint>
</service>
behaviors- contents of the tag describing the behavior of the service and the end-point
行为- 描述服务和端点行为的标签内容
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
Index.html- the executor, what your code can be called as
Index.html- 执行器,您的代码可以称为
<html>
<head>
<script>
...
</script>
<style>
...
</style>
</head>
<body>
...
</body>
</html>
script- contents of the tag describing the executable in JavaScript
script- 在 JavaScript 中描述可执行文件的标签内容
window.onload = function () {
document.getElementById("xhr").onclick = function () {
var xhr = new XMLHttpRequest();
xhr.onload = function () { alert(xhr.responseText); }
xhr.open("GET", "RestService.svc/xml/Viltersten");
xhr.send();
}
}
style- contents of the tag describing the appearance
style- 描述外观的标签内容
.clickable
{
text-decoration: underline;
color: #0000ff;
}
body- contents of the tag describing the markup structure
body- 描述标记结构的标签内容
<ul>
<li>XML output <a href="RestService.svc/xml/123">
<span class="clickable">here</span></a></li>
<li>JSON output <a href="RestService.svc/json/123">
<span class="clickable">here</span></a></li>
<li>XHR output <span id="xhr" class="clickable">here</span></li>
Everything is stored in a project called DemoRest. I created my own files for declaration and implementation of the service, removing the default ones. The directives of usingas well as the XML version declaration are omitted for spacial reasons.
一切都存储在一个名为DemoRest. 我创建了自己的文件来声明和实现服务,删除了默认文件。由于using空间原因,省略了指令以及 XML 版本声明。
Now the response can be retrieved using the following URL.
现在可以使用以下 URL 检索响应。
localhost:12345/RestService.svc/xml/Konrad
localhost:12345/RestService.svc/json/Viltersten
- Does anybody else get it to work too?
- Any suggestions on improvement or clarification?
- 其他人也让它工作吗?
- 关于改进或澄清的任何建议?
回答by carlosfigueira
If you define your service endpoint as a WebHttp endpoint (a.k.a. REST endpoint), you'll get what you want. The easiest way to do that is to use the WebServiceHostFactoryin your svc file:
如果您将服务端点定义为 WebHttp 端点(又名 REST 端点),您将获得您想要的。最简单的方法是WebServiceHostFactory在 svc 文件中使用:
Service1.svc.
Service1.svc。
<%@ ServiceHost Language="C#" Debug="true" Service="YourNamespace.Service1"
Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
Or you can define the endpoint without the factory, by defining that it will use the webHttpBindingand have a <webHttp/>behavior:
或者,您可以在没有工厂的情况下定义端点,通过定义它将使用webHttpBinding并具有<webHttp/>行为:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="MyBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="YourNamespace.Service1">
<endpoint address=""
behaviorConfiguration="MyBehavior"
binding="webHttpBinding"
contract="YourNamespace.IService1" />
</service>
</services>
</system.serviceModel>
Update: Since some people were having issues, I wrote a full example of using XMLHttpRequestto talk to the service listed above. The code can be found at https://github.com/carlosfigueira/WCFQuickSamples/tree/master/WCFForums/QuickWebCode1(look for StackOverflow_13345557), and it's mostly listed here.
更新:由于有些人遇到了问题,我写了一个完整的示例,XMLHttpRequest用于与上面列出的服务对话。代码可以在https://github.com/carlosfigueira/WCFQuickSamples/tree/master/WCFForums/QuickWebCode1(查找 StackOverflow_13345557)中找到,它主要在这里列出。
Service code(notice that I'm using JSON as the response, but XML works just as well):
服务代码(请注意,我使用 JSON 作为响应,但 XML 也能正常工作):
namespace StackOverflow_13345557
{
[ServiceContract]
public interface IService1
{
[WebGet(ResponseFormat = WebMessageFormat.Json)]
string Ping();
[WebGet(ResponseFormat = WebMessageFormat.Json)]
string PingWithParameters(int a, string b);
}
public class Service1 : IService1
{
public string Ping()
{
return "Hello";
}
public string PingWithParameters(int a, string b)
{
return string.Format("Hello {0} - {1}", a, b);
}
}
}
.SVC file- notice no usage of the Factoryattribute, since I'm defining the endpoint via configuration:
.SVC 文件- 注意没有使用该Factory属性,因为我通过配置定义端点:
<%@ ServiceHost Language="C#" Debug="true" Service="StackOverflow_13345557.Service1"
CodeBehind="StackOverflow_13345557.svc.cs" %>
web.config:
网络配置:
<system.serviceModel>
<services>
<service name="StackOverflow_13345557.Service1">
<endpoint address=""
behaviorConfiguration="WithWebHttp"
binding="webHttpBinding"
bindingConfiguration="WithJSONP"
contract="StackOverflow_13345557.IService1" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="WithWebHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="WithJSONP" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
</system.serviceModel>
HTML page accessing service(body only):
HTML 页面访问服务(仅正文):
<body>
<script type="text/javascript">
function StackOverflow_13345557_Test(passParameters) {
var baseUrl = "/StackOverflow_13345557.svc";
var cacheBuster = new Date().getTime(); // to prevent cached response; development only
var url;
if (passParameters) {
url = baseUrl + "/PingWithParameters?a=123&b=john+doe&_=" + cacheBuster;
} else {
url = baseUrl + "/Ping?_=" + cacheBuster;
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
document.getElementById("result").innerText = xhr.responseText;
}
}
xhr.open('GET', url, true);
xhr.send();
}
</script>
<input type="button" value="StackOverflow 13345557 (no params)" onclick="StackOverflow_13345557_Test(false);" /><br />
<input type="button" value="StackOverflow 13345557 (with params)" onclick="StackOverflow_13345557_Test(true);" /><br />
<div id='result'></div>
</body>
One more update: added a self-contained, minimal project at https://skydrive.live.com/redir?resid=99984BBBEC66D789!6355with the code listed above.
另一个更新:在https://skydrive.live.com/redir?resid=99984BBBEC66D789!6355上添加了一个自包含的最小项目,其中包含上面列出的代码。

