Config中System.Object的WCF已知类型
我正在尝试在配置中指定一个已知类型,但我遇到的问题是它派生自Object。 我可以通过属性指定已知类型。 但在这种情况下,我需要从配置中使其工作。
这是一个例子。 以下工作正常:
[ServiceContract] [ServiceKnownType(typeof(MyData))] public interface IContract { [OperationContract] void Send(object data); } [DataContract] public class MyData { [DataMember] public string Message { get; set; } }
但是,如果我删除ServiceKnownType属性并将以下内容放入配置中:
我得到一个ConfigurationErrorsException,消息“属性’type的值’无效。错误是:System.Object类型不能用作config中的声明类型。”
无论如何通过配置使这项工作?
答案结果certificate是不可能单独在配置文件中做我想做的事情。 上面的配置对应于DataContracts上使用的[KnownType]属性。 似乎无法在配置中实现[ServiceKnownType]。
另一种方法是将[ServiceKnownType(methodName,type)]属性与自定义配置节一起使用。 新配置如下所示:
合同:
[ServiceContract] [ServiceKnownType("GetServiceKnownTypes", typeof(KnownTypeHelper))] public interface IContract { [OperationContract] void Send(object data); } [DataContract] public class MyData { [DataMember] public string Message { get; set; } }
包含返回已知类型列表的回调的帮助程序类
public static class KnownTypeHelper { public static IEnumerable GetServiceKnownTypes(ICustomAttributeProvider provider) { List result = new List (); ServiceKnownTypesSection serviceKnownTypes = (ServiceKnownTypesSection)ConfigurationManager.GetSection("serviceKnownTypes"); DeclaredServiceElement service = serviceKnownTypes.Services[((Type)(provider)).AssemblyQualifiedName]; foreach (ServiceKnownTypeElement knownType in service.KnownTypes) { result.Add(knownType.Type); } return result; } }
有关创建自定义配置部分的信息,请访问:
http://msdn.microsoft.com/en-us/library/2tw134k3.aspx
http://msdn.microsoft.com/en-us/library/system.configuration.configurationcollectionattribute.aspx
我不确定它是否是设计的,但如果您没有声明具有已知类型的服务合同,则下面的KnownTypeHelper不会抛出错误。 (即可选择将已知类型添加到服务合同中)。
using System; using System.Collections.Generic; using System.Configuration; using System.Reflection; /// /// Helper for finding the known types for Wcf Services from a configuration file. /// public static class KnownTypeHelper { /// /// Gets the known types for the service from a configuration file. /// /// /// The provider. /// /// /// The known types for the service from a configuration file. /// public static IEnumerable GetServiceKnownTypes(ICustomAttributeProvider provider) { var result = new List (); var serviceKnownTypes = (ServiceKnownTypesSection)ConfigurationManager.GetSection("serviceKnownTypes"); if (serviceKnownTypes != null) { var service = serviceKnownTypes.Services[((Type)provider).AssemblyQualifiedName]; if (service != null) { foreach (ServiceKnownTypeElement knownType in service.KnownTypes) { result.Add(knownType.Type); } } } return result; } }
为了节省别人创建配置类的麻烦,
注意:没有validation程序集限定类型名称。 如果有人想添加适当的属性来执行此操作,请执行此操作。
using System.Configuration; /// /// Section for configuration known types for services. /// public class ServiceKnownTypesSection : ConfigurationSection { /// /// Gets services. /// [ConfigurationProperty("declaredServices", IsDefaultCollection = false)] [ConfigurationCollection(typeof(DeclaredServiceElement), AddItemName = "serviceContract", CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)] public DeclaredServiceElementCollection Services { get { return (DeclaredServiceElementCollection)base["declaredServices"]; } } } /// /// Collection of declared service elements. /// public class DeclaredServiceElementCollection : ConfigurationElementCollection { /// /// Gets the service for which known types have been declared for. /// /// /// The key of the service. /// public new DeclaredServiceElement this[string key] { get { return (DeclaredServiceElement)BaseGet(key); } set { var element = BaseGet(key); var index = this.BaseIndexOf(element); if (BaseGet(index) != null) { BaseRemoveAt(index); } BaseAdd(index, value); } } /// /// When overridden in a derived class, creates a new . /// /// /// A new . /// protected override ConfigurationElement CreateNewElement() { return new DeclaredServiceElement(); } /// /// Gets the element key for a specified configuration element when overridden in a derived class. /// /// /// An that acts as the key for the specified . /// /// /// The to return the key for. /// protected override object GetElementKey(ConfigurationElement element) { return ((DeclaredServiceElement)element).Type; } } /// /// The service for which known types are being declared for. /// public class DeclaredServiceElement : ConfigurationElement { /// /// Gets or sets Type. /// [ConfigurationProperty("type", IsRequired = true, IsKey = true)] public string Type { get { return (string) this["type"]; } set { this["type"] = value; } } /// /// Gets KnownTypes. /// [ConfigurationProperty("knownTypes", IsDefaultCollection = false)] [ConfigurationCollection(typeof(DeclaredServiceElement), AddItemName = "knownType", CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)] public ServiceKnownTypeElementCollection KnownTypes { get { return (ServiceKnownTypeElementCollection)base["knownTypes"]; } } } /// /// A collection of known type elements. /// public class ServiceKnownTypeElementCollection : ConfigurationElementCollection { /// /// Gets an known type with the specified key. /// /// /// The key of the known type. /// public new ServiceKnownTypeElement this[string key] { get { return (ServiceKnownTypeElement)BaseGet(key); } set { var element = BaseGet(key); var index = this.BaseIndexOf(element); if (BaseGet(index) != null) { BaseRemoveAt(index); } BaseAdd(index, value); } } /// /// When overridden in a derived class, creates a new . /// /// /// A new . /// protected override ConfigurationElement CreateNewElement() { return new ServiceKnownTypeElement(); } /// /// Gets the element key for a specified configuration element when overridden in a derived class. /// /// /// An that acts as the key for the specified . /// /// /// The to return the key for. /// protected override object GetElementKey(ConfigurationElement element) { return ((ServiceKnownTypeElement)element).Type; } } /// /// Configuration element for a known type to associate with a service. /// public class ServiceKnownTypeElement : ConfigurationElement { /// /// Gets or sets TypeString. /// [ConfigurationProperty("type", IsRequired = true, IsKey = true)] public string TypeString { get { return (string)this["type"]; } set { this["type"] = value; } } /// /// Gets or sets Type. /// public Type Type { get { return Type.GetType(this.TypeString); } set { this["type"] = value.AssemblyQualifiedName; } } }