by WebSurfer
19. September 2010 18:06
ASP.NET Web サービスで、普通の System.Data.DataTable を送ろうとすると、シリアル化できないというエラーが出て送ることができません。
Visual Studio のウィザードを使って作る「型付 DataTable」はシリアル化できるようで、それを利用すれば Web サービスから送信でき、受信側でも問題なく「型付 DataTable」を再生して利用できます。
では、DataSet はどうでしょうか?
理由は分かりませんが、自分が検証した結果によれば、少々制約がありました。忘れないように、以下に書いておきます。
(1) 制約その1
「型付 DataTable」を普通の System.Data.DataSet を入れ物に使って送信することができます。ただし受信側で、DataSet から取得した DataTable を送り側で設定した型にキャストできないという制約があります。
送信側(Web サービス)の例
[WebMethod(Description = "普通の DataSet に型付 DataTable を入れて返します")]
public DataSet CreateOrdinaryDataSet()
{
DataSet ds = new DataSet();
NorthwindDataSetTableAdapters.CustomersTableAdapter adapterCustomers =
new NorthwindDataSetTableAdapters.CustomersTableAdapter();
ds.Tables.Add(adapterCustomers.GetDataByCountry("Germany"));
NorthwindDataSetTableAdapters.ProductsTableAdapter adapterProducts =
new NorthwindDataSetTableAdapters.ProductsTableAdapter();
ds.Tables.Add(adapterProducts.GetDataByCategoryID(1));
return ds;
}
受信側(アプリケーション)の例
MyService.Service wsMyService = new MyService.Service();
DataSet ds = wsMyService.CreateOrdinaryDataSet();
// キャストできずエラーとなる。
// MyService.NorthwindDataSet.CustomersDataTable table =
// (MyService.NorthwindDataSet.CustomersDataTable)ds.Tables[0];
// これは OK
DataTable table = ds.Tables[0];
dataGridView1.DataSource = table;
(2) 制約その2
「型付 DataSet」を入れ物にして送る場合、「型付 DataSet」のメンバーの「型付 DataTable」に Fill するようにしないと、アプリケーション側で DataSet を再生できないという制約があります。
送信側・・・これは OK
[WebMethod (Description="型付 DataSet を返します")]
public NorthwindDataSet CreateDataSet()
{
NorthwindDataSet ds = new NorthwindDataSet();
NorthwindDataSetTableAdapters.CustomersTableAdapter adapterCustomers =
new NorthwindDataSetTableAdapters.CustomersTableAdapter();
adapterCustomers.FillByCountry(ds.Customers, "UK");
NorthwindDataSetTableAdapters.ProductsTableAdapter adapterProducts =
new NorthwindDataSetTableAdapters.ProductsTableAdapter();
adapterProducts.FillByCategoryID(ds.Products, 1);
return ds;
}
送信側・・・これは NG
[WebMethod(Description = "型付 DataSet を返します(その2)")]
public NorthwindDataSet CreateDataSet2()
{
NorthwindDataSet ds = new NorthwindDataSet();
NorthwindDataSetTableAdapters.CustomersTableAdapter adapterCustomers =
new NorthwindDataSetTableAdapters.CustomersTableAdapter();
ds.Tables.Add(adapterCustomers.GetDataByCountry("Germany"));
NorthwindDataSetTableAdapters.ProductsTableAdapter adapterProducts =
new NorthwindDataSetTableAdapters.ProductsTableAdapter();
ds.Tables.Add(adapterProducts.GetDataByCategoryID(1));
return ds;
}
アプリケーション側で CreateDataSet2 を呼び出すと XmlSchemaException がスローされます。エラーメッセージによると、「NorthwindDataSet.xsd:Customers の複数の定義があるため、コンテンツ モデルがあいまいになっています。」ということだそうです。