WCF 如何透過 Hashtable 傳回 Dataset

似乎沒有簡單的做法,不管是 Hashtable 或 Dictionary<string,object>,在伺服器端產生 Proxy 後,會以ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType 代表該類別,Code Generate 內容:

[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays")]
public partial class ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType
{
    private string keyField;
    private object valueField;
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=0)]
    public string Key
    {
        get
        {
            return this.keyField;
        }
        set
        {
            this.keyField = value;
        }
    }

線上說明 Collection Types in Data Contracts 似乎只能解決 Collection 內含簡單序列化的內容,例如,若以 Hashtable 傳遞,可要求產生的 Proxy 使用 Hashtable

svcutil.exe http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/mex /r:C:WINDOWSMicrosoft.NETFrameworkv2.0.50727System.dll /ct:System.Collections.Hashtable

若要包含 Enum,可以搭配 Passing Enum values into WCF Service operations,透過 Hashtable/Dictionary 可以正常傳遞。

一旦 Dictionary<string,object> 內含需要序列化的物件,如 DataSet,就會錯誤,測試如下:

//IService

namespace WcfServiceLibrary1
{
    [ServiceContract]
    [ServiceKnownType(typeof(EnumTable))]
    //[ServiceKnownType(typeof(myHashtable))]
    public interface IService1
    {
        [OperationContract]
        myHashtable GetData(myHashtable Params);

        [OperationContract]
        myHashtable GetData2(EnumTable enumName,myHashtable Params);

        [OperationContract]
        DataSet GetData3(EnumTable enumName, myHashtable Params);
    }

    [DataContract(Namespace = "http://MyNameSpace.DataContracts/2009/10", Name = "EnumTable")]
    public enum EnumTable
    {
        [EnumMember()]
        Customers = 0,
        [EnumMember()]
        Employees = 1,
        [EnumMember()]
        Orders = 2
    }

    [DataContract()]
//    [KnownType(typeof(DataSet))]
    public class myHashtable
    {
        [DataMember]
        //public Hashtable myTable;
        public Dictionary<string, object> myTable;
    }
}

 

//Service

public myHashtable GetData(myHashtable Params)
{
    string strSQL = "SELECT {0} FROM {1} WHERE {2}";
    switch ((EnumTable)Params.myTable["TableName"])
    {
        case EnumTable.Customers:
            strSQL = string.Format(strSQL, "CustomerID,CompanyName,ContactName","Customers", (string)Params.myTable["Params"]);
            break;
        case EnumTable.Employees:
            strSQL = string.Format(strSQL, "EmployeeID,FirstName,LastName","Employees", (string)Params.myTable["Params"]);
            break;
        case EnumTable.Orders:
            strSQL = string.Format(strSQL, "OrderID,EmployeeID,CustomerID","Orders", (string)Params.myTable["Params"]);
            break;
    }
    SqlDataAdapter adp = new SqlDataAdapter(strSQL, "Data Source=.;Initial Catalog=Northwind;Integrated Security=SSPI");
    DataSet ds=new DataSet();
    adp.Fill(ds);
    myHashtable ht = new myHashtable();
    ht.myTable = new Dictionary<string,object>();
    ht.myTable["ds"] = ds;
    ht.myTable["TableName"] = ((EnumTable)Params.myTable["TableName"]).ToString();
    return ht;
}

 

//Client

Service1Client obj = new Service1Client();
//Hashtable ht=new Hashtable();
//Dictionary<string, object> ht = new Dictionary<string, object>();
myHashtable ht = new myHashtable();
ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType[] ugly=new ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType[2];
ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType wow= new ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType();
wow.Key = "TableName";
wow.Value = (EnumTable)Enum.Parse(typeof(EnumTable), TextBox1.Text);
ugly[0] = wow;
ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType wow2 = new ArrayOfKeyValueOfstringanyTypeKeyValueOfstringanyType();
wow2.Key = "Params";
wow2.Value = TextBox2.Text;
ugly[1] = wow2;
ht.myTable = ugly;
myHashtable htRet=(myHashtable)obj.GetData(ht);

image

上述錯誤的詳細資料

image

一些人有相同問題,沒人有解…

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/2f80a807-3b9c-433c-a8b4-e2d465af0a97/

http://social.msdn.microsoft.com/forums/en-US/wcf/thread/18d70e2b-dd34-4895-9754-61b758185689/

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s

%d 位部落客按了讚: