4

我已经设置了以下界面。

[ServiceContract]
public interface IService1
{
  [OperationContract]
  String Ping();
}

其实现如下。

public class Service1 : IService1
{
  public string Ping(){ return "Pong"; }
}

根据 VS 中的测试应用程序,它在调用时可以正常工作。我的问题是,当我输入http://localhost:12345/Service1.svc(或者可能是 Service1.svc?PingService.svc/Ping)时,我希望文本出现在屏幕上。它完全关闭还是我在正确的树上吠叫?

当然,“ Pong ”最终将是一个 XML 结构。

编辑

在下面@carlosfigueira 的回复中提供的设置为解决方案的建议提供了一个很好的结构,但不幸的是,在我的机器上使用 F5 运行时会出现错误消息。似乎需要元数据,端点也是如此。

4

2 回答 2

9

我终于得到了完全的 PO 并开始了全面的业务联系。这是我制作的——它可以在我的机器上运行,我希望这不是本地现象。:)

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 - 实现,您的代码对客户端的实际作用

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 - 配置,您的代码在到达客户端的过程中被处理的内容

<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.serviceModel>
    <services>
      ...
    </services>
    <behaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

services - 描述服务性质的标签内容

<service name="DemoRest.RestService" 
         behaviorConfiguration="ServiceBehavior">
  <endpoint address="" binding="webHttpBinding" 
            contract="DemoRest.IRestService" 
            behaviorConfiguration="web"></endpoint>
</service>

行为- 描述服务和端点行为的标签内容

<serviceBehaviors>
  <behavior name="ServiceBehavior">
    <serviceMetadata httpGetEnabled="true"/>
    <serviceDebug includeExceptionDetailInFaults="true"/>
  </behavior>
</serviceBehaviors>

<endpointBehaviors>
  <behavior name="web">
    <webHttp/>
  </behavior>
</endpointBehaviors>

Index.html - 执行者,你的代码可以称为什么

<html>
  <head>
    <script>
      ...
    </script>
    <style>
      ...
    </style>
  </head>
  <body>
    ...
  </body>
</html>

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 - 描述外观的标签内容

.clickable
{
  text-decoration: underline;
  color: #0000ff;
}

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>

一切都存储在一个名为DemoRest. 我为服务的声明和实现创建了自己的文件,删除了默认文件。using由于篇幅原因,省略了的指令和XML 版本声明。

现在可以使用以下 URL 检索响应。

localhost:12345/RestService.svc/xml/Konrad
localhost:12345/RestService.svc/json/Viltersten
  1. 其他人也让它工作吗?
  2. 有什么改进或澄清的建议吗?
于 2012-11-12T14:55:48.040 回答
1

如果您将服务端点定义为 WebHttp 端点(又名 REST 端点),您将得到您想要的。最简单的方法是WebServiceHostFactory在 svc 文件中使用:

服务 1.svc。

<%@ ServiceHost Language="C#" Debug="true" Service="YourNamespace.Service1"
                Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

或者您可以定义没有工厂的端点,通过定义它将使用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>

更新:由于有些人有问题,我写了一个完整的例子来使用XMLHttpRequest上面列出的服务。该代码可以在https://github.com/carlosfigueira/WCFQuickSamples/tree/master/WCFForums/QuickWebCode1找到(查找 StackOverflow_13345557),并且大部分都在此处列出。

服务代码(请注意,我使用 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 文件- 注意没有使用该Factory属性,因为我通过配置定义端点:

<%@ ServiceHost Language="C#" Debug="true" Service="StackOverflow_13345557.Service1"
                CodeBehind="StackOverflow_13345557.svc.cs" %>

网络配置

<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 页面访问服务(仅正文):

<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>

另一个更新:在https://skydrive.live.com/redir?resid=99984BBBEC66D789!6355添加了一个独立的最小项目,上面列出了代码。

于 2012-11-12T14:43:48.680 回答