Web客户端错误:" text / xml"响应消息的内容与绑定的内容类型不匹配(text / xml; charset = utf-8)

时间:2016-10-14 15:31:24

标签: c# .net web-services wcf ws-security

使用Framework 4.0编写了一个用C#.NET编写的Visual Studio 2010 WCF Web服务。 我的Web服务调用使用HTTPS,WS-Security和Mtom的Java Web服务,我需要处理结果。

表示Java Web服务不需要

<u:Timestamp><u:Created><u:Expires></u:Timestamp>
标题中的

部分。

当前问题: 当我测试对listStuff的调用时,对Web服务调用的响应显示了我正在寻找的数据(使用Fiddler)但是我在WCF测试客户端中收到以下错误:

&#34;文本/ XML&#34;响应消息的内容与绑定的内容类型不匹配(text / xml; charset = utf-8)。如果使用自定义编码器,请确保正确实现IsContentTypeSupported方法。

我如何处理我正在调用的Web服务未返回&#34; charset = utf-8&#34;他们的回应?

tried <globalization requestEncoding="utf-8" responseEncoding="utf-8"/>
tried <globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" culture="en-GB" uiCulture="en-GB"/>
tried <textMessageEncoding messageVersion="Soap12"/>
tried <mtomMessageEncoding/>

看起来WS-Security和Mtom正在运作。

用于创建我的网络服务的步骤:

打开Visual Studio 2010。

档案 - &gt;新 - &gt;项目

WCF - &gt;服务申请。 将名称更改为MyWebService。 将位置更改为C:\ MyWebService。 将解决方案名称更改为MyWebService。 单击“确定”按钮。

显示Service1.svc.cs文件。

右键单击公共类名称Service1。 重构 - &gt;改名。 更改名称:EstuffService。 单击确定按钮,然后单击应用按钮。

打开Service1.svc.cs。 添加以下方法:

    public String listStuff()
    {
        return "Called listStuff()";
    }

打开IService1.cs并将以下内容添加到公共接口IService1。

    [OperationContract]
    String listStuff();

现在的测试方法。

选择Service1.svc.cs文件。 调试 - &gt;开始调试。 打开WCF测试客户端窗口。 双击listStuff。 打开listStuff选项卡。 单击“调用”按钮。 显示安全警告。 单击确定按钮。 响应包含“Called listStuff()&#34;在价值领域。

务!现在加入JAVA WEB服务逻辑。

添加服务参考。

解决方案资源管理器 - &gt;右键单击服务参考 - &gt;添加服务参考。

输入地址:     https://the.stuff.com/createFiling?wsdl

点击“转到”按钮。

展开createStuffService。

单击CreateMTOMInterface。

输入命名空间:createStuffService。

单击“确定”按钮。

项目 - &gt;创建发布设置。 选择Application选项卡。 目标框架:.NET Framework 4。 显示目标框架更改消息。 单击是按钮。

对默认代码进行了以下更改:

//////////////////////////////////////////////////////////////////////////
// Service1.svc.cs
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using MyWebService.createStuffService;
using System.IdentityModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.Security.Cryptography;
using System.IdentityModel.Tokens;

namespace MyWebService
{
    public class EstuffService : IService1
    {
        public String listStuff()
        {
            CreateMTOMInterfaceClient estuffService = getEstuffService();
            try
            {
                stuff[] stuffs = estuffService.listStuff();
                return "listStuff returned " + stuffs.Length.ToString() + " rows.";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            // was - return "Called listStuff()";
        }

        // ADDED the following to use the CustomeCredentials
        public CreateMTOMInterfaceClient getEstuffService()
        {
            CreateMTOMInterfaceClient service = new CreateMTOMInterfaceClient();

            service.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
            service.ChannelFactory.Endpoint.Behaviors.Add(new CustomCredentials());

            service.ClientCredentials.UserName.UserName = "[UserName]";
            service.ClientCredentials.UserName.Password = "[Password]";

            return service;
        }
        // END ADDED
    }

    // ADDED 
    // The following logic comes from 
    // https://weblog.west-wind.com/posts/2012/nov/24/wcf-wssecurity-and-wse-nonce-authentication
    // with a couple of changes as noted.  Thanks Rick Strahl.

    public class CustomCredentials : ClientCredentials
    {
        public CustomCredentials()
        { }

        protected CustomCredentials(CustomCredentials cc)
            : base(cc)
        { }

        public override System.IdentityModel.Selectors.SecurityTokenManager CreateSecurityTokenManager()
        {
            return new CustomSecurityTokenManager(this);
        }

        protected override ClientCredentials CloneCore()
        {
            return new CustomCredentials(this);
        }
    }

    public class CustomSecurityTokenManager : ClientCredentialsSecurityTokenManager
    {
        public CustomSecurityTokenManager(CustomCredentials cred)
            : base(cred)
        { }

        public override System.IdentityModel.Selectors.SecurityTokenSerializer CreateSecurityTokenSerializer(System.IdentityModel.Selectors.SecurityTokenVersion version)
        {
            return new CustomTokenSerializer(System.ServiceModel.Security.SecurityVersion.WSSecurity11);
        }
    }

    public class CustomTokenSerializer : WSSecurityTokenSerializer
    {
        public CustomTokenSerializer(SecurityVersion sv)
            : base(sv)
        { }

        protected override void WriteTokenCore(System.Xml.XmlWriter writer,
                                                System.IdentityModel.Tokens.SecurityToken token)
        {
            UserNameSecurityToken userToken = token as UserNameSecurityToken;

            string tokennamespace = "o";

            DateTime created = DateTime.UtcNow;  // was .Now;
            string createdStr = created.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); // was "yyyy-MM-ddThh:mm:ss.fffZ"

            // unique Nonce value - encode with SHA-1 for 'randomness'
            // in theory the nonce could just be the GUID by itself
            string phrase = Guid.NewGuid().ToString();
            var nonce = GetSHA1String(phrase);

            // in this case password is plain text
            // for digest mode password needs to be encoded as:
            // PasswordAsDigest = Base64(SHA-1(Nonce + Created + Password))
            // and profile needs to change to
            //string password = GetSHA1String(nonce + createdStr + userToken.Password);

            string password = userToken.Password;

            writer.WriteRaw(string.Format(
            "<{0}:UsernameToken u:Id=\"" + token.Id +
            "\" xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" +
            "<{0}:Username>" + userToken.UserName + "</{0}:Username>" +
            "<{0}:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">" +
            password + "</{0}:Password>" +
            "<{0}:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" +
            nonce + "</{0}:Nonce>" +
            "<u:Created>" + createdStr + "</u:Created></{0}:UsernameToken>", tokennamespace));
        }

        protected string GetSHA1String(string phrase)
        {
            SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
            byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase));
            return Convert.ToBase64String(hashedDataBytes);
        }

    }
    // END ADDED 
}
//
// END Service1.svc.cs
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// IService1.cs
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace MyWebService
{
    [ServiceContract]
    public interface IService1
    {
        // ADDED
        [OperationContract]
        String listStuff();
        // END ADDED
    }

}
//
// END IService1.cs
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Web.config
//
<?xml version="1.0"?>
<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
    <!--
        The <authentication> section enables configuration 
        of the security authentication mode used by 
        ASP.NET to identify an incoming user. 
    -->
    <authentication mode="Windows"/>
    <!--
        The <customErrors> section enables configuration 
        of what to do if/when an unhandled error occurs 
        during the execution of a request. Specifically, 
        it enables developers to configure html error pages 
        to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
         <error statusCode="403" redirect="NoAccess.htm" />
         <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
    -->
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
    <!-- ADDED -->
    <!--tried <globalization requestEncoding="utf-8" responseEncoding="utf-8"/>-->
    <!--tried <globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" culture="en-GB" uiCulture="en-GB"/> -->
    <!-- END ADDED -->
  </system.web>
  <!-- 
      The system.webServer section is required for running ASP.NET AJAX under Internet
      Information Services 7.0.  It is not necessary for previous version of IIS.
  -->
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="createStuffServiceSoapBinding">
          <security mode="Transport"/>
        </binding>
        <binding name="createStuffServiceSoapBinding1"/>
      </basicHttpBinding>
      <!-- Added -->
      <!--tried <textMessageEncoding messageVersion="Soap12"/>-->
      <!--tried <mtomMessageEncoding/>-->
      <customBinding>
        <binding name="CustomSoapBinding">
          <security includeTimestamp="false" authenticationMode="UserNameOverTransport" defaultAlgorithmSuite="Basic256" requireDerivedKeys="false" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"/>
          <textMessageEncoding messageVersion="Soap11"/>
          <httpsTransport maxReceivedMessageSize="2000000000"/>
        </binding>
      </customBinding>
      <!-- End Added -->
    </bindings>
    <client>
      <!-- Was binding="basicHttpBinding" bindingConfiguration="createStuffServiceSoapBinding"-->
      <endpoint address="https://the.stuff.com/createFiling" binding="customBinding" bindingConfiguration="CustomSoapBinding" contract="createStuffService.CreateMTOMInterface" name="createStuffServicePort"/>
    </client>
    <services>
      <service behaviorConfiguration="MyWebService.Service1Behavior" name="MyWebService.EstuffService">
        <endpoint address="" binding="wsHttpBinding" contract="MyWebService.IService1">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <!--tried <serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/>-->
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyWebService.Service1Behavior">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
//
// END Web.config
//////////////////////////////////////////////////////////////////////////

这是我的Fiddler调用结果。

*** REQUEST Captured using Telerik Fiddler Web Debugger ***
POST https://the.stuff.com/services/createFiling HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: the.stuff.com
Content-Length: 1279
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

<s:Envelope 
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData 
xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">
uIDPo8CYUJmfemFDgV85fb9Z8dwBAAAAHYQCoVVch0SXHY5oNUdGeXF1Nv5vBlNMnDbXQEH7yAoACQAA
</VsDebuggerCausalityData>
<o:Security 
s:mustUnderstand="1" 
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken 
u:Id="uuid-920edd97-b092-4f62-a2f2-0463dd064628-10" 
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<o:Username>
[UserName]
</o:Username>
<o:Password 
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
[Password]
</o:Password>
<o:Nonce 
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
SsN9bPcfZEsAulkbEtN2FksKXWg=
</o:Nonce>
<u:Created>2016-10-12T16:44:30.147Z</u:Created>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<listStuff xmlns="http://efile.the.stuff.com/"/>
</s:Body>
</s:Envelope>
*** END REQUEST Captured using Telerik Fiddler Web Debugger ***

*** RESPONSE Captured using Telerik Fiddler Web Debugger ***
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
XM: ttc1a
Content-Type: multipart/related; type="application/xop+xml"; 
boundary="uuid:89bea26c-8f7d-4dcf-8809-c5cb9697a1f0"; start="<root.message@cxf.apache.org>"; start-info="text/xml"
Transfer-Encoding: chunked
Date: Wed, 12 Oct 2016 16:44:32 GMT
Set-Cookie: F5-SESSION-PERSIST=889397770.63520.0000; path=/
X-FRAME-OPTIONS: SAMEORIGIN
Content-Length: 53173

--uuid:89bea26c-8f7d-4dcf-8809-c5cb9697a1f0
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>

<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body><ns2:listStuffResponse xmlns:ns2="http://efile.the.stuff.com/">
<stuff><id>1</id><name>Stuff1</name><abbreviation>A001</abbreviation></stuff>
... left out stuff 2 to 536 ...
<stuff><id>537</id><name>Stuff537</name><abbreviation>A537</abbreviation></stuff>
</ns2:listStuffResponse>
</soap:Body>
</soap:Envelope>
--uuid:89bea26c-8f7d-4dcf-8809-c5cb9697a1f0--
*** END RESPONSE Captured using Telerik Fiddler Web Debugger ***

这是我从WCF测试客户端获得的XML结果。

*** REQUEST Captured from WCF Test Client ***
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" 
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/IService1/listStuff</a:Action>
<a:MessageID>urn:uuid:8a03d3ad-dd79-4745-b9bb-a55ce293d314</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
</s:Header>
<s:Body>
<listStuff xmlns="http://tempuri.org/" />
</s:Body>
</s:Envelope>
*** END REQUEST Captured from WCF Test Client ***

*** RESPONSE Captured from WCF Test Client ***
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" 
xmlns:a="http://www.w3.org/2005/08/addressing" 
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1" 
u:Id="_2">http://tempuri.org/IService1/listStuffResponse</a:Action>
<a:RelatesTo u:Id="_3">urn:uuid:26883546-39ea-44e0-83b2-d3cee32ba8b0</a:RelatesTo>
<o:Security s:mustUnderstand="1" 
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="uuid-303895ea-d557-4df1-a665-2f94391dd40d-15">
<u:Created>2016-10-12T16:44:32.350Z</u:Created>
<u:Expires>2016-10-12T16:49:32.350Z</u:Expires>
</u:Timestamp>
<c:DerivedKeyToken u:Id="uuid-303895ea-d557-4df1-a665-2f94391dd40d-13" 
xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">
<o:SecurityTokenReference>
<o:Reference URI="urn:uuid:6e0ba079-fc3c-4ae9-9186-e0e3f928a113" 
ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/sct" />
</o:SecurityTokenReference>
<c:Offset>0</c:Offset>
<c:Length>24</c:Length>
<c:Nonce>UvseoObRVJeMp2Dv3t/5tg==</c:Nonce>
</c:DerivedKeyToken>
<c:DerivedKeyToken 
u:Id="uuid-303895ea-d557-4df1-a665-2f94391dd40d-14" 
xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">
<o:SecurityTokenReference>
<o:Reference 
URI="urn:uuid:6e0ba079-fc3c-4ae9-9186-e0e3f928a113" 
ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/sct" />
</o:SecurityTokenReference>
<c:Nonce>gFfWI8QjzYJH8kh/9dzDgA==</c:Nonce>
</c:DerivedKeyToken>
<e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:DataReference URI="#_1" />
<e:DataReference URI="#_4" />
</e:ReferenceList>
<e:EncryptedData Id="_4" 
Type="http://www.w3.org/2001/04/xmlenc#Element" 
xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod 
Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference>
<o:Reference 
ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/dk" 
URI="#uuid-303895ea-d557-4df1-a665-2f94391dd40d-14" />
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>... left out the CipherValue ...</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</o:Security>
</s:Header>
<s:Body u:Id="_0">
<listStuffResponse xmlns="http://tempuri.org/">
<listStuffResult>
The content type multipart/related; type="application/xop+xml"; 
boundary="uuid:89bea26c-8f7d-4dcf-8809-c5cb9697a1f0"; start="&lt;root.message@cxf.apache.org&gt;"; 
start-info="text/xml" of the response message does not match the content type of the binding (text/xml; charset=utf-8). 
If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes 
of the response were: '--uuid:89bea26c-8f7d-4dcf-8809-c5cb9697a1f0
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: &lt;root.message@cxf.apache.org&gt;

&lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
&lt;soap:Body&gt;
&lt;ns2:listStuffResponse 
xmlns:ns2="http://efile.the.stuff.com/"&gt;
&lt;stuff&gt;&lt;id&gt;1&lt;/id&gt;&lt;name&gt;Stuff001&lt;/name&gt;&lt;abbreviation&gt;X001&lt;/abbreviation&gt;&lt;/stuff&gt;
... left out stuff 2 to 6 ...
&lt;stuff&gt;&lt;id&gt;7&lt;/id&gt;&lt;name&gt;Stuff007&lt;/name&gt;&lt;abbreviation&gt;X007&lt;/abbreviation&gt;&lt;'.
</listStuffResult>
</listStuffResponse>
</s:Body>
</s:Envelope>
*** END RESPONSE Captured from WCF Test Client ***

0 个答案:

没有答案