51

DataTable を返したい WCF サービスがあります。DataTables を返すことが適切な方法であるかどうかについては、これがよく議論されるトピックであることを私は知っています。ちょっと脇に置きましょう。

以下のように、DataTable を最初から作成すると、何の問題もありません。テーブルが作成され、データが入力され、クライアントに返されます。すべて問題ありません。

[DataContract]
public DataTable GetTbl()
{
    DataTable tbl = new DataTable("testTbl");
    for(int i=0;i<100;i++)
    {
        tbl.Columns.Add(i);
        tbl.Rows.Add(new string[]{"testValue"});
    }
    return tbl;
}

ただし、外に出てデータベースにアクセスしてテーブルを作成するとすぐに、以下のように、「基になる接続が閉じられました: 接続が予期せず閉じられました」という CommunicationException が発生します。

[DataContract]
public DataTable GetTbl()
{
    DataTable tbl = new DataTable("testTbl");
    //Populate table with SQL query

    return tbl;
}

テーブルはサーバー側で正しく設定されています。これは、ループして返されたテスト テーブルよりもかなり小さく、クエリは小さくて高速です。ここでは、タイムアウトや大規模なデータ転送の問題はありません。同じ正確な関数と DataContracts/ServiceContracts/BehaviorContracts が使用されています。

テーブルに値が入力される方法が、テーブルが正常に返されることに影響するのはなぜですか?

4

8 に答える 8

83

同様の問題を抱えている人のために、私は自分の問題を解決しました。それは数倍でした。

  • Darrenが提案し、Paulがバックアップしたように、構成のMax..Sizeプロパティを拡大する必要がありました。SvcTraceViewerユーティリティはこれを判断するのに役立ちましたが、それでも常に最も役立つエラーメッセージが表示されるとは限りません。
  • また、クライアント側でサービスリファレンスを更新すると、構成が適切に更新されない場合があるようです(たとえば、サーバーで構成値を変更しても、クライアントで常に適切に更新されるとは限りません。最大値を変更する必要がありました。デバッグ中に、クライアント側とサーバー側の両方でプロパティのサイズを複数回設定します)
  • DataTableをシリアル化するには、名前を付ける必要があります。デフォルトのコンストラクターはテーブルに名前を付けないため、次のようになります。

    return new DataTable();
    

    シリアル化できませんが、次の場合に発生します。

    return new DataTable("someName");
    

    パラメータとして渡されたものは何でもテーブルに名前を付けます。

    TableNameDataTableのプロパティに文字列を割り当てることで、テーブルにいつでも名前を付けることができることに注意してください。

    var table = new DataTable();
    table.TableName = "someName";
    

うまくいけば、それは誰かを助けるでしょう。

于 2008-09-03T19:14:32.540 に答える
15

このような種類の WCF エラー (実際には多くのことがわかりません) を診断する最善の方法は、トレースを有効にすることです。web.config ファイルに、次を追加します。

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel" 
              switchValue="Information" 
              propagateActivity="true">
        <listeners>
          <add name="ServiceModelTraceListener" 
               type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
               initializeData="wcf-traces.svclog"/>
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

結果のファイルは、.NET Framework SDK (または Visual Studio) に含まれている SvcTraceViewer.exe ユーティリティで開くことができます。私のマシンでは、%PROGRAMFILES%\Microsoft SDKs\Windows\v6.0A\Bin\SvcTraceViewer.exe にあります。

エラー メッセージ (赤の太字) を探すだけで、具体的に何が問題なのかがわかります。

于 2008-08-23T18:56:50.147 に答える
5

すべてのバインディング属性に最大値を設定する以外。

Webサービスから渡す/返す各テーブルにはテーブル名が必要です。つまり、table.tablenameプロパティが空白であってはなりません。

于 2010-12-21T13:33:49.277 に答える
5

Datable をデータセットに追加し、テーブルを次のように返しました...

DataTable result = new DataTable("result");

//linq to populate the table

Dataset ds = new DataSet();
ds.Tables.Add(result);
return ds.Tables[0];

それが役に立てば幸い :)

于 2011-10-24T08:29:51.093 に答える
4

必要な属性は、OperationContract (インターフェイス上) / Operation Behavior (メソッド上) です。

[ServiceContract]
public interface ITableProvider
{
    [OperationContract]
    DataTable GetTbl();
}


[OperationBehavior]
public DataTable GetTbl(){
    DataTable tbl = new DataTable("testTbl");
    //Populate table with SQL query

    return tbl;
}

また、...サービス構成だと思います...で、エラーを送信できるように指定したいと思います。メッセージサイズが大きすぎるなどのエラーが発生している可能性があります。リーダーのクォータなどをいじることで修正できます。

デフォルトでは、wsHttpBinding は 65 KB 程度の受信サイズ クォータを持っているため、シリアル化されたデータ テーブルの XML がそれを超えると、エラーがスローされます (そして、データ テーブルが 65 KB を超えてデータが格納されていることを 95% 確信しています) )。

リーダー クォータなどの設定をweb.config/で変更しapp.configたり、コードでバインディング インスタンスに設定したりできます。しかし、ええ、デフォルトで変更していない場合、おそらくそれが問題です。

WSHttpBindingBase メンバー- ReaderQuotas プロパティと MaxReceivedMessageSize プロパティを見てください。

于 2008-08-15T20:35:00.977 に答える
2

クォータを使い果たした可能性があります。データテーブルが、接続で許可されている最大パケット サイズを超えています。

おそらく、接続時にMaxReceivedMessageSizeMaxBufferSizeをより高い値に設定する必要があります。

于 2008-10-24T13:33:35.373 に答える
1

datatableWCF サービスのように、戻り値の型が失敗する理由は 3 つあります。

  • 次のようなデータテーブル名を指定する必要があります。

    MyTable=new DataTable("tableName");
    
  • WCF サービスのクライアント側で参照を追加する場合は、再利用可能な dll を選択しますsystem.data

  • datatableのようにメンバ変数に属性を指定する

    [DataMember]
    public DataTable MyTable{ get; set; }
    
于 2016-12-02T05:14:45.053 に答える
0

ダレンはおそらく正しいと思います。WCFに提供されているデフォルト値は笑えるほど小さく、それらにぶつかると、追跡が困難なエラーが発生する可能性があります。単純なテストケース以外のことをしようとするとすぐに表示されるようです。クライアントとサーバーの両方のさまざまな構成(サイズ)設定に関連していることが判明したデバッグの問題を認めたいよりも多くの時間を無駄にしました。私はそれらのほとんどすべてを変更することになったと思います。MaxBufferPoolSize、MaxBufferSize、MaxConnections、MaxReceivedMessageSizeなど。

そうは言っても、SvcTraceViewerユーティリティも素晴らしいです。思ったほど役に立たなかったケースがいくつかありましたが、全体としては、通信フローとエラーを分析するための優れたツールです。

于 2008-09-02T14:18:57.300 に答える