0

DataSetWPF アプリケーションから WCF サービスにを送信したいと考えています。空を送信するDataSetと正常に動作します。しかしDataSet、30DataTableでは例外があります

リモート サーバーが予期しない応答を返しました: (400) 不正な要求。

私の運用契約は次のとおりです。

  [OperationContract]
  string InsertDataToDatabase(DataSet ds);

DataSetを WCF サービスに送信する最良の方法はどれですか?

クライアントApp.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_ICommunication" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192"  maxArrayLength="2147483647"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:49486/Communication.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICommunication"
                contract="CommunicationReference.ICommunication" name="BasicHttpBinding_ICommunication" />
        </client>
    </system.serviceModel>
</configuration>

サービスWeb.Config

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <connectionStrings>
    <add name="ConName" connectionString="Data Source=WIN-7;Initial Catalog=ABC; User ID=sa; Password=****"/>        
  </connectionStrings>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding maxBufferSize="2147483647"
                 maxReceivedMessageSize="2147483647">
          <readerQuotas maxStringContentLength="2147483647" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>      
      <serviceBehaviors>
        <behavior>
           <!--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"/>
          <serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="1000" maxConcurrentInstances="1600" />
        </behavior>
      </serviceBehaviors>
    </behaviors>    
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>  
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>  
</configuration>
4

1 に答える 1

5

データ サイズの問題で 400 エラー メッセージが表示された記憶はありませんが、いくつか試してみることができます。

ここでいくつかのことが起こっています。まず、サービスの構成ファイルによると、.NET 4.0 を使用しています。これは、デフォルトのエンドポイントを使用していることを意味します。config で明示的に定義されたエンドポイントがないため、フレームワークがエンドポイントを作成します。そして、適切なバインディング (BasicHttpBindingこの場合) のデフォルト値を使用します。つまり、定義したバインディングの値を変更しても、それらは有効になりません。さらに、デフォルト値を使用したデフォルトの動作も受け取ります。

バインディングでより高い値を設定してみてくださいmaxReceivedMessageSize- デフォルトは 65536 です - そしてmaxStringContentLength(デフォルトは 8192 ~ 8K です)。のサイズを大きくする場合は、 のサイズも(少なくとも) 同じ値maxStringContentLengthまで大きくする必要があります。maxBufferSize

エンドポイントが明示的に定義されていないため、エンドポイントを作成して定義したバインディングをそれに割り当てるか、定義をデフォルトにする必要があります。

まず、バインディングの更新バージョン (より大きなデータを処理するため) は次のようになります (変更が必要な関連部分のみが示されています - 簡潔にするために残りは省略しています)。私はかなり大きな数を選びました - formaxBufferSizemaxReceivedMessageSizemax は Int64 の最大値であり、 formaxStringContentLengthの max 値は Int32 の最大値です。

<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_ICommunication" 
             maxBufferSize="2147483647" 
             maxReceivedMessageSize="2147483647">
      <readerQuotas maxStringContentLength="2147483647" />
    </binding>
  </basicHttpBinding>
</bindings>

次に、このバインディングをサービス エンドポイントに割り当てる必要があります。特にエンドポイントが 1 つしかない場合、最も簡単な方法は、バインディング定義をデフォルトより上に作成することです。これを行うには、要素name内の属性を単に省略します。binding例えば:

<bindings>
  <basicHttpBinding>
    <binding maxBufferSize="2147483647" 
             maxReceivedMessageSize="2147483647">
      <readerQuotas maxStringContentLength="2147483647" />
    </binding>
  </basicHttpBinding>
</bindings>

name上記の (削除された) 構成には属性がないことに注意してください。

2 番目の方法は、エンドポイントを作成し、定義したバインディング構成をそれに割り当てることです。例えば:

<services>
  <service name="MyServiceName">
      <endpoint address="" 
                binding="basicHttpBinding" 
                bindingConfiguration="BasicHttpBinding_ICommunication"
                contract="MyService.IMyContract" />
  </service>
</services>

また、私は行ったことはありませんが、人々がサービスの動作で要素のmaxItemsInObjectGraph属性を増やすのを見てきました。dataContractSerializerMSDN のドキュメントに基づいて、データ コントラクトを使用していないため、あなたのケースには当てはまらないと思います。ただし、これを修正するためのオプションをできるだけ多く提供するには、次のように、動作グループでエンドポイントの動作を定義することで調整できます。

<behaviors>
  <endpointBehaviors>
    <behavior name="LargeDataBehavior">
      <dataContractSerializer maxItemsInObjectGraph="2147483646" />
    </behavior>
  </endpointBehaviors>
</behaviors>

繰り返しますが、.NET 4.0 を使用しているため、この動作を (name属性を省略して) デフォルトの動作として定義するか、次のように (上記のエンドポイントの例を使用して) 定義済みのエンドポイントに割り当てる必要があります。

<endpoint address=""
          behaviorConfiguration="LargeDataBehavior" 
          binding="basicHttpBinding" 
          bindingConfiguration="BasicHttpBinding_ICommunication"
          contract="MyService.IMyContract" />

WCF Streamingもご覧ください。

于 2013-04-19T07:04:19.543 に答える