HTTP Post 以测试 WCF REST 端点。使用 XML 格式的合同

HTTP Post to test WCF REST End Point. Using an XML formatted contract

我有一个带有合同的网络服务,需要使用 XML。 (它还有其他 JSON 修饰的合约,它们被用户很好地消费)

我想通过 REST 端点测试 XML 合同。 (它在使用默认 SOAP 上下文的单元测试中运行良好) 我在单元测试中使用你自己的 Http Post 的努力给出错误 400

大约 3 天后,测试代码看起来像一个炸弹站点,我仍然卡住了。

能有多难???

VS2013 框架 4.5.1.

我想做的就是用单元测试(或 Fiddler 或 Postman)证明 REST 端点将处理 Post 和 xml有效负载。

如果有人可以提供一些示例 HTTP POST c# 代码,他们希望使用下面的简单测试合同,我将不胜感激。我尝试过的网络上可用的变体比我记得的要多,现在我完全糊涂了。

测试合同:

[WebInvoke(
        Method = "POST",
        UriTemplate = "Testing",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Xml,
        RequestFormat = WebMessageFormat.Xml)]
    [OperationContract]
    void Testing(TestData test);

这是由以下人员实施的:

 public void Testing(TestData test)
    {
        int x = test.MyInt;
        string y = test.MyString;
    }


 [DataContract]
public class TestData
{
    [DataMember]
    public int MyInt { get; set; }
    [DataMember]
    public string MyString { get; set; }
}

单元测试代码为:

                string url = "http://myService.svc/REST/Testing";
            DellbertCouponParking.TestData t = new DellbertCouponParking.TestData();
            t.MyInt = 2;
            t.MyString = "HelloWorld";

            XmlSerializer xsSubmit = new XmlSerializer(typeof(DellbertCouponParking.TestData));
            StringWriter sw = new StringWriter();
            XmlWriter writer = XmlWriter.Create(sw);
            xsSubmit.Serialize(writer, t);
            string xml = sw.ToString();

            byte[] formData = System.Text.Encoding.ASCII.GetBytes(xml);
            HttpWebRequest req = WebRequest.Create(new Uri(url))
                                     as HttpWebRequest;
            req.Method = "POST";
            req.ContentLength = formData.Length;
            req.ContentType = "text/xml; encoding='utf-8'";
            // Send the request:
            using (Stream requestStream = req.GetRequestStream())
            {
                requestStream.Write(formData, 0, formData.Length);
                requestStream.Close();
            }

            // Pick up the response:
            string result = null;
            using (HttpWebResponse resp = req.GetResponse()
                                          as HttpWebResponse)
            {
                StreamReader reader =
                    // ReSharper disable once PossibleNullReferenceException
                    new StreamReader(resp.GetResponseStream());
                result = reader.ReadToEnd();
            }
            Assert.IsTrue(result.Length > 0);

有 'JSON' 个 REST 端点服务正常的合同。 这是我第一次尝试 xml 合同。

自从我最初发布这个问题后,我通过发布到 httpbin 证明测试代码是可以的。org/post

所以我想我的问题归结为:

更多信息:

web.config 成立:

<system.serviceModel>
<client>
  <endpoint address="https://sec.paymentexpress.com/PxF/pxf.svc"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPxFusion"
    contract="DPSFusion.IPxFusion" name="BasicHttpBinding_IPxFusion" />
</client>
<bindings>
  <basicHttpBinding>
    <binding name="basicHttp" maxBufferPoolSize="20000000" maxBufferSize="20000000"
      maxReceivedMessageSize="20000000">
      <readerQuotas maxDepth="32" maxStringContentLength="200000000"
        maxArrayLength="200000000" />
    </binding>
    <binding name="BasicHttpBinding_IPxFusion" maxBufferPoolSize="20000000"
      maxBufferSize="20000000" maxReceivedMessageSize="20000000">
      <readerQuotas maxDepth="32" maxStringContentLength="200000000"
        maxArrayLength="200000000" />
      <security mode="Transport" />
    </binding>
  </basicHttpBinding>
  <webHttpBinding>
    <binding name="JsonBinding" maxBufferSize="20000000" maxBufferPoolSize="20000000"
      maxReceivedMessageSize="20000000">
      <readerQuotas maxDepth="32" maxStringContentLength="200000000"
        maxArrayLength="200000000" />
    </binding>       
  </webHttpBinding>
</bindings>
<services>
  <service name="CouponParkingWCF.CouponService">
    <endpoint name="SoapEndPoint" address="SOAP" binding="basicHttpBinding" contract="CouponParkingWCF.ICouponService" />
    <endpoint name="JSON" address="REST" behaviorConfiguration="JsonBehavior" binding="webHttpBinding" contract="CouponParkingWCF.ICouponService" />       
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="JsonBehavior">
      <webHttp />
    </behavior>        
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<!-- <protocolMapping>
  <add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />

IIS 日志显示: 2015-07-20 23:13:25 192.168.0.235 POST /wsCouponParking/CouponParking.svc/REST/Testing - 80 - 192.168.0.38 - - 400 0 0 203

对于我所缺少的任何指导,我将不胜感激。 谢谢 鲍勃

经过多次肆无忌惮的挫折后,我找到了答案。 目前对微软的绝对仇恨允许如此脆弱的结构进入野外。 我们并非都是 xml 和端点专家,我和我都希望在为 Json 和 XML 端点装饰的 WCF 合同之间有一个预期的一致行为。

您使用 JSON 签订了无数服务和数据合同,然后您认为您只需为 XML 服务合同稍作改动,它就会推出。对对对!

吐槽完毕。

分四部分回答:

1) 为你的 Web.config 获取一个像样的块来处理 XML 和 JSON 端点。 我永远感谢 Satchi,他将此作为问题 WCF REST return 单一方法作为 JSON 和 XML

的答案发布
<endpoint address="XML" binding="webHttpBinding" bindingConfiguration="webHttpBindingXML" contract="xxxxxx.Ixxxxxxx" behaviorConfiguration="RestXMLEndpointBehavior"/>
<endpoint address="JSON" binding="webHttpBinding" bindingConfiguration="webHttpBindingJSON" contract="xxxxxxxx.Ixxxxxxxxx" behaviorConfiguration="RestJSONEndpointBehavior"/>

<endpointBehaviors>

  <behavior name="RestJSONEndpointBehavior">
    <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json"/>
  </behavior>
  <behavior name="RestXMLEndpointBehavior">
    <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Xml"/>
  </behavior>

</endpointBehaviors>        
<webHttpBinding>
  <binding name="webHttpBindingXML"/>
  <binding name="webHttpBindingJSON"/>
</webHttpBinding> 

2) 给[DataContract]装饰添加NameSpace属性这个必不可少 不记得我在哪里找到的这是我在网上闲逛但感谢发布它的人。

 [DataContract(Namespace = "")]//The Namespace attribute is essential.
public class TestData
{

    [DataMember]
    public string MyString { get; set; }
}

3) 去除服务合同的装饰。再次感谢 Satchi。

 //[WebInvoke(
    //    Method = "POST",
    //    UriTemplate = "Testing",
    //    BodyStyle = WebMessageBodyStyle.Bare,
    //    ResponseFormat = WebMessageFormat.Xml,
    //    RequestFormat = WebMessageFormat.Xml)]
    [OperationContract]
    void Testing(TestData test);

4) 使用上述 Web.config 添加时提供的帮助页面。这在一定程度上减轻了我的仇恨,这是一个很棒的功能。 例如http://myserver/myProject/myService.svc/XML/help/ 这将为您显示测试请求示例 XML 正文的正确结构。

我正在为 WCF 项目使用 Framework 4.5.1,但仍然需要此解决方案。