哈希表如何在WCF中工作?
问题描述:
我有问题。哈希表如何在WCF中工作?
考虑下面
IService1.cs
[ServiceContract]
public interface IService1
{
[OperationContract]
Hashtable GetHashTableCollection();
[OperationContract]
List<A> GetARecords();
}
[DataContract]
public class A
{
[DataMember]
public int MyProperty { get; set; }
[DataMember]
public Hashtable MyTable { get; set; }
}
Service1.cs
public class Service1 : IService1
{
public Hashtable GetHashTableCollection()
{
Hashtable hashtable = new Hashtable();
hashtable.Add("Area", 1000);
hashtable.Add("Perimeter", 55);
hashtable.Add("Mortgage", 540);
return hashtable;
}
public List<A> GetARecords()
{
List<A> Alist = new List<A>();
Alist.Add(new A { MyProperty = 1, MyTable = GetHashTableCollection() });
Alist.Add(new A { MyProperty = 2, MyTable = GetHashTableCollection() });
return Alist;
}
}
和客户机应用是作为下
private void button1_Click(object sender, EventArgs e)
{
ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
var r1 = sc.GetHashTableCollection();
var r2 = sc.GetARecords();
}
它工作正常,没有任何问题。 HashTable已被转换为Dictionary对象。
我的印象是,因为HashTable使用IDictionary,所以它应该在编译时失败(发生在3.5)。
无法隐式转换类型 'System.Collections.Generic.Dictionary' 到 'System.Collections.Hashtable'
但是,它的工作。怎么样?
我是否缺少任何基本概念?或者DataContractSerializer正在做这项工作?或者在dot.net 4.0中改变了一些东西?
它是什么以及它为什么工作?
答
它基于IDictionary
。 WCF将IDictionary视为Dictionary<object, object>
,它在WSDL上公开。你可以有一个自定义的类实现IDictionary
,并且行为将是相同的。例如,如果您运行以下任一项目,并使用svcutil
或添加服务引用来为该服务生成代理(您有IDictionary
类型),则您将在客户端中获得Dictionary<object, object>
。
public class *_15471185
{
[ServiceContract]
public interface IService1
{
[OperationContract]
Hashtable GetHashTableCollection();
[OperationContract]
List<A> GetARecords();
}
[DataContract]
public class A
{
[DataMember]
public int MyProperty { get; set; }
[DataMember]
public Hashtable MyTable { get; set; }
}
public class Service : IService1
{
public Hashtable GetHashTableCollection()
{
Hashtable hashtable = new Hashtable();
hashtable.Add("Area", 1000);
hashtable.Add("Perimeter", 55);
hashtable.Add("Mortgage", 540);
return hashtable;
}
public List<A> GetARecords()
{
List<A> Alist = new List<A>();
Alist.Add(new A { MyProperty = 1, MyTable = GetHashTableCollection() });
Alist.Add(new A { MyProperty = 2, MyTable = GetHashTableCollection() });
return Alist;
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "");
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
host.Open();
Console.WriteLine("Host opened");
var factory = new ChannelFactory<IService1>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
var proxy = factory.CreateChannel();
Console.WriteLine(proxy.GetHashTableCollection());
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
public class *_15471185_b
{
[ServiceContract]
public interface IService1
{
[OperationContract]
MyDic GetHashTableCollection();
[OperationContract]
List<A> GetARecords();
}
public class MyDic : IDictionary
{
public IDictionary dic = new Hashtable();
public void Add(object key, object value)
{
dic.Add(key, value);
}
public void Clear()
{
dic.Clear();
}
public bool Contains(object key)
{
return dic.Contains(key);
}
public IDictionaryEnumerator GetEnumerator()
{
return dic.GetEnumerator();
}
public bool IsFixedSize
{
get { return dic.IsFixedSize; }
}
public bool IsReadOnly
{
get { return dic.IsReadOnly; }
}
public ICollection Keys
{
get { return dic.Keys; }
}
public void Remove(object key)
{
dic.Remove(key);
}
public ICollection Values
{
get { return dic.Values; }
}
public object this[object key]
{
get
{
return dic[key];
}
set
{
dic[key] = value;
}
}
public void CopyTo(Array array, int index)
{
dic.CopyTo(array, index);
}
public int Count
{
get { return dic.Count; }
}
public bool IsSynchronized
{
get { return dic.IsSynchronized; }
}
public object SyncRoot
{
get { return dic.SyncRoot; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)dic).GetEnumerator();
}
}
[DataContract]
public class A
{
[DataMember]
public int MyProperty { get; set; }
[DataMember]
public MyDic MyTable { get; set; }
}
public class Service : IService1
{
public MyDic GetHashTableCollection()
{
MyDic hashtable = new MyDic();
hashtable.Add("Area", 1000);
hashtable.Add("Perimeter", 55);
hashtable.Add("Mortgage", 540);
return hashtable;
}
public List<A> GetARecords()
{
List<A> Alist = new List<A>();
Alist.Add(new A { MyProperty = 1, MyTable = GetHashTableCollection() });
Alist.Add(new A { MyProperty = 2, MyTable = GetHashTableCollection() });
return Alist;
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "");
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
host.Open();
Console.WriteLine("Host opened");
var factory = new ChannelFactory<IService1>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
var proxy = factory.CreateChannel();
Console.WriteLine(proxy.GetHashTableCollection());
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}