2

Webサービスにアクセスしようとしています(これもWCFを使用してコーディングされていると思いますが、制御できません)。例外が発生します。

System.ServiceModel.FaultException:WSE012:次の情報が欠落しているため、入力は有効なSOAPメッセージではありませんでした:アクション。
サーバースタックトレース:

at System.ServiceModel.Channels.ServiceChannel.HandleReply(
   ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action,
   Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs,
   TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(
   IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

[0]で再スローされた例外:

at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(
   IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(
   MessageData& msgData, Int32 type)
at ClientName.ProjectName.Services.ServiceName.ServiceNameSoap.CallServiceName(
   Request request)
at ClientName.ProjectName.Scheduler.ThirdPartyName.ProcessServiceName.Execute(
   Object state) in ...\ProcessServiceName.cs:line 65

の呼び出しコードは次のProcessServiceName.Executeとおりです。

Request serviceRequest = request.BuildServiceRequest();
Result result = client.CallServiceName(serviceRequest);
LogServiceErrors(db, request.ServiceNameRequestId, result.errors);

例外は、サービスリファレンスによって自動生成されたWCFコードを直接呼び出して;を呼び出す2番目の行から発生します。このメソッドは、データベースオブジェクトを取得し、それをWebサービスに必要なオブジェクトに変換するだけです。System.ServiceModel.ClientBase<T>. Channel.CallServiceName(request)BuildServiceRequest

App.config(これはWindowsサービス内で呼び出されます)の関連部分は次のとおりです。

<system.serviceModel>
   <bindings>
      <webHttpBinding>
         <binding name="webBinding">
         </binding>
      </webHttpBinding>
      <wsHttpBinding>
         <binding name="ThirdPartySoap" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00"
          sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false"
          hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288"
          maxReceivedMessageSize="65536" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true">
            <readerQuotas maxDepth="32" maxStringContentLength="8192"
             maxArrayLength="16384" maxBytesPerRead="4096"
             maxNameTableCharCount="16384"/>
            <security mode="Transport">
               <transport clientCredentialType="Basic" proxyCredentialType="None"
                realm="www.serviceprovider.com"/>
               <message clientCredentialType="UserName"
                algorithmSuite="Default"/>
            </security>
         </binding>
      </wsHttpBinding>
   </bindings>
   <client>
      <endpoint name="ServiceNameSoap"
       address="https://www.serviceprovider.com/ServiceName.asmx"
       binding="wsHttpBinding" bindingConfiguration="ThirdPartySoap"
       contract="ServiceName.ServiceNameSoap"/>
   </client>
</system.serviceModel>

実際のWebサービス作業を行うすべてのコードがWCF内からのものであることを考えると、問題が何であるかはよくわかりませんが、おそらく、App.configそれを防ぐために少し異なるものが必要です。

グーグルを見て、私は何の助けも見つけていません。StackOverflowでは、2011年9月のこの未回答のWCFの質問は役に立ちません。カスタムバインディング(2009年11月の回答WSEに関するリンク)は役に立ちません(そして私はそれらをほとんど理解していません) 。 2009年11月のフォーラムの回答と2009年10月のColdFusionの回答はどちらも無関係です。私が見ている他のすべてのGoogleヒットは、これらのリンクの複製です。

どんな援助も大歓迎です!


編集して詳細を追加

Wiktor Zychlaは、問題は(理論的には)プロキシクラスにある可能性があることを正しく指摘しています。ただし、これらのクラスは、自動的に生成されたクラスから完全に編集されていません。例えば:

using System.CodeDom.Compiler;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace ClientName.ProjectName.Services.ServiceName
{
   [GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
   public interface ServiceNameSoapChannel : ServiceNameSoap, IClientChannel {}

   [System.Diagnostics.DebuggerStepThroughAttribute()]
   [GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
   public partial class ServiceNameSoapClient : ClientBase<ServiceNameSoap>,
     ServiceNameSoap
   {
     public ServiceNameSoapClient() { }

     public ServiceNameSoapClient(string endpointConfigurationName) : 
       base(endpointConfigurationName) { }

     public ServiceNameSoapClient(string endpointConfigurationName,
       string remoteAddress) :
       base(endpointConfigurationName, remoteAddress) { }

     public ServiceNameSoapClient(string endpointConfigurationName,
       EndpointAddress remoteAddress) :
       base(endpointConfigurationName, remoteAddress) { }

     public ServiceNameSoapClient(Binding binding,
       EndpointAddress remoteAddress) : base(binding, remoteAddress) { }

     public Result CallServiceName(Request request)
     { return base.Channel.CallServiceName(request); }
   }
}

他のすべてのプロキシクラスも同様に自動生成されたコードから編集されていません(空白と名前空間の最適化のためにここで編集したので、StackOverflow内の画面によりよく適合します;usingステートメントを追加した3つの名前空間はすべてで完全に修飾されていますClientName.ProjectName.Services.ServiceNameこれらのサンプルで編集した名前空間と同様に、クラス参照。

WCFメッセージログを追加すると、メッセージログに次のように表示されます。(これは上記のコードとは異なるサービス呼び出しからのものですが、同じ例外をスローします。これは、このサービス呼び出しが単純であるため、何らかの理由ですべてのサービス呼び出しがログに記録されていないためです。私が行った唯一の編集は、水平スクロールなしで読みやすいエラーメッセージ。)

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
  <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
    <EventID>0</EventID>
    <Type>3</Type>
    <SubType Name="Information">0</SubType>
    <Level>8</Level>
    <TimeCreated SystemTime="2013-01-18T12:00:04.7166250Z" />
    <Source Name="System.ServiceModel.MessageLogging" />
    <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
    <Execution ProcessName="ClientName.ProjectName.Scheduler" ProcessID="8600" ThreadID="10" />
    <Channel/>
    <Computer>MachineNameRedacted</Computer>
  </System>
  <ApplicationData>
    <TraceData>
      <DataItem>
        <MessageLogTraceRecord Time="2013-01-18T12:00:04.7166250+00:00" Source="TransportSend" Type="System.ServiceModel.Dispatcher.OperationFormatter+OperationFormatterMessage" xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
          <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
            <s:Header>
              <a:Action s:mustUnderstand="1">http://www.serviceprovider.com/RedactedActionName</a:Action>
              <a:MessageID>urn:uuid:395d6394-5f4b-4954-8df0-8fb82d17072a</a:MessageID>
              <a:ReplyTo>
                <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
              </a:ReplyTo>
              <a:To s:mustUnderstand="1">https://www.serviceprovider.com/ServiceName.asmx</a:To>
            </s:Header>
            <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
              <RedactedActionName xmlns="http://www.serviceprovider.com">
                <brandId>2</brandId>
              </RedactedActionName>
            </s:Body>
          </s:Envelope>
        </MessageLogTraceRecord>
      </DataItem>
    </TraceData>
  </ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
  <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
    <EventID>0</EventID>
    <Type>3</Type>
    <SubType Name="Information">0</SubType>
    <Level>8</Level>
    <TimeCreated SystemTime="2013-01-18T12:00:04.7635000Z" />
    <Source Name="System.ServiceModel.MessageLogging" />
    <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
    <Execution ProcessName="ClientName.ProjectName.Scheduler" ProcessID="8600" ThreadID="10" />
    <Channel/>
    <Computer>MachineNameRedacted</Computer>
  </System>
  <ApplicationData>
    <TraceData>
      <DataItem>
        <MessageLogTraceRecord Time="2013-01-18T12:00:04.7635000+00:00" Source="TransportReceive" Type="System.ServiceModel.Channels.BufferedMessage" xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
          <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
            <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope">
              <wsa:Action>http://schemas.xmlsoap.org/ws/2004/08/addressing/fault</wsa:Action>
              <wsa:MessageID>urn:uuid:b72c6f30-8409-4b55-8c79-056d82f990a5</wsa:MessageID>
              <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
            </env:Header>
            <soap:Body>
              <soap:Fault>
                <soap:Code>
                  <soap:Value>soap:Sender</soap:Value>
                </soap:Code>
                <soap:Reason>
                  <soap:Text xml:lang="en">
                    WSE012: The input was not a valid SOAP message because
                    the following information is missing: action.
                  </soap:Text>
                </soap:Reason>
              </soap:Fault>
            </soap:Body>
          </soap:Envelope>
        </MessageLogTraceRecord>
      </DataItem>
    </TraceData>
  </ApplicationData>

さらに詳細:ServiceNameSoapインターフェース

Wiktor Zychlaが要求したように、自動生成されたコードからのインターフェイスServiceNameSoap宣言は、画面にぴったり合うように(したがってusing)、クライアントの機密名を編集するためにのみ編集されています。

using System.ServiceModel;

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel","4.0.0.0")]
[ServiceContractAttribute(Namespace="https://www.serviceprovider.com/",
    ConfigurationName="ServiceName.ServiceNameSoap")]
public interface ServiceNameSoap
{
    [OperationContractAttribute(
        Action="https://www.serviceprovider.com/ServiceName",
        ReplyAction="*")]
    [XmlSerializerFormatAttribute(SupportFaults=true)]
    [ServiceKnownTypeAttribute(typeof(ClientRequest))]
    [return: MessageParameterAttribute(Name="result")]
    ClientName.ProjectName.Services.ServiceName.Result CallServiceName(
        ClientName.ProjectName.Services.ServiceName.Request request);
}
4

3 に答える 3

1

(OPとの共同作業)

サービスが.asmxエンドポイントで公開されていることを確認しました。これは、これがwcfサービスではなく、古いasp.netサービスであることを示しています。wcfとは対照的にAsp.netWebサービスの構成オプションは非常に限られており、ws / webバインディングをサポートしていません(基本httpのみ)。私のアドバイスは、古いタイプのプロキシに切り替えて、wsdl.exeツールで生成することです。構成は必要なく、wsHttpBindingを使用することはできませんが、少なくともサービスを呼び出すことができるはずです。

于 2013-01-21T10:50:15.297 に答える
1

勝者がいます…</h2>

Wiktorのコメントにより、WCFとWSE3.0の間の相互運用性を調べ、メソッドが次のように変更されるようにオーバーライドして使用MessageVersion.Soap12WSAddressingAugust2004してみました。CustomBindingBinding.CreateBindingElementsClientName.ProjectName.Services. ServiceName.ServiceNameSoapClient.CallServiceName

public Result CallServiceName(Request request)
{
    return base.Channel.CallServiceName(request);
}

(元の質問のように)に:

using System.ServiceModel.Channels;

public Result CallTestDrive(Request request)
{
    BindingElementCollection elements
        = base.Endpoint.Binding.CreateBindingElements();
    elements.Find<MessageEncodingBindingElement>().MessageVersion
        = MessageVersion.Soap12WSAddressingAugust2004;
    base.Endpoint.Binding = new CustomBinding(elements);

    return base.Channel.CallTestDrive(request);
}

( Nicholas AllenのWCFブログのサービスのバインディングの変更から適応されたコード)。

これで私の問題は解決したようです。やっと。

WiktorとJohnSaundersに感謝します; あなたの助けがなければ、私はこれにたどり着きませんでした。


編集:以下の別の失敗した試み

完全を期すために、私が試したがうまくいかなかった別の方法を含めます。また、質問WCF CustomBinding構成に対するこの回答の指示に従って、名前空間にカスタムバインディングクラスを作成してみましたClientName.ProjectName.ServiceName

using System.ServiceModel;
using System.ServiceModel.Channels;

public class CustomWsHttpBinding : WSHttpBinding
{
    public override BindingElementCollection CreateBindingElements()
    {
        BindingElementCollection elements = base.CreateBindingElements();

        MessageEncodingBindingElement encodingElement
          = elements.Find<MessageEncodingBindingElement>();
        encodingElement.MessageVersion
          = MessageVersion.Soap12WSAddressingAugust2004;

        return elements;
    }
}

そしてそれを設定に追加します:

<system.serviceModel>
    <extensions>
        <bindingExtensions>
            <add name="CustomWsHttpBinding"
             type="ClientName.ProjectName.ServiceName.CustomWsHttpBinding, ClientName.ProjectName.ServiceName" />
        </bindingExtensions>
    </extensions>
    <bindings>
        <CustomWsHttpBinding>
            <binding name="ServiceNameSoap" closeTimeout="00:01:00"
             openTimeout="00:01:00" receiveTimeout="00:10:00"
             sendTimeout="00:01:00" allowCookies="false"
             bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
             maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
             messageEncoding="Text" textEncoding="utf-8"
             useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192"
                 maxArrayLength="16384" maxBytesPerRead="4096"
                 maxNameTableCharCount="16384"/>
                <security mode="Transport">
                    <transport clientCredentialType="Basic"
                     proxyCredentialType="None" realm="www.serviceprovider.com"/>
                    <message clientCredentialType="UserName"
                     algorithmSuite="Default"/>
                </security>
            </binding>
        </CustomWsHttpBinding>
    </bindings>
    <!-- ... -->
</system.serviceModel>
于 2013-01-21T15:18:41.747 に答える
1

私はこれが2歳であることを知っていますが、私は最も簡単な解決策を与えると思いました。私は上記の答えを再ハッシュしている可能性があります。秘訣は、私たちが事前にws-*で受け入れている古い学校のasmxサービスを理解することです。WS-Addressing機能には2つのバージョン(おそらくそれ以上)があります-2005年8月と問題のある2004年8月。これらはSOAPUIで確認でき、.asmxサービスをテストするときにWS-Aバージョンを手動で「200408」に変更する必要があります。基本的に、ws-addressingヘッダーを次の場所から変更するだけです。

<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">

<soap:Header xmlns:wsa="http://www.w3.org/2004/08/addressing">

問題は、WCFでこれをどのように行うかということです。簡単に言うと、上記のように、wsHttpBindingを使用するのではなく、カスタムバインディングを使用してメッセージバージョンを設定します。さらにAdieuがなければ、関連するWebConfig:

<system.serviceModel> <client> <endpoint address="http://localhost/some_old_school_garbage_service/adapterws.asmx" binding="customBinding" bindingConfiguration="AdapterWSSoap" contract="AdapterWS.AdapterWSSoap" name="LodestarASMX" /> </client> <bindings> <customBinding> <binding name="AdapterWSSoap" > <security authenticationMode="UserNameOverTransport" allowInsecureTransport="True"></security> <textMessageEncoding messageVersion="Soap12WSAddressingAugust2004"></textMessageEncoding> <httpTransport/> </binding> </customBinding>

于 2015-12-28T20:49:59.540 に答える