我有一个WCF服务,我已经编写了接受调用者传递给它的对象,这些服务已经用告诉服务如何查找字符串表示的属性进行了修饰。例如,该服务可以将CAR_ID 1转换为"丰田",CAR_ID 2转换为"本田"等等。
那部分效果很好。我遇到一些重大问题的地方是我加载类型的想法,因此WCF可以处理序列化和反序列化而不会丢失对象属性的关键属性。我的目标是在远程共享上放置一个文件夹,组织中的人员可以放弃他们装饰的.dll,然后调用传递在已删除的.dll中定义的对象的服务。在大多数情况下,这是很好的,除了一件事:我有随机问题锁定放在.dll上,所以我无法在遥控器上更新它们份额。
我希望将路径定义移动到指向安装服务的本地文件夹,或者能够自定义服务器端。就目前的情况而言,我必须发布用于在我的界面中提取已知类型的代码,这意味着我输入的任何路径都是从调用者的角度评估的,不是我喜欢的服务。有没有办法摆脱这种困境?
以下是我的合同副本。
[ServiceKnownType("RegisterKnownTypes", typeof(MyStringTypeHelper))]
[ServiceContract]
public interface IMyStringParser
{
[OperationContract]
string GetStringRepresentation(object target);
[OperationContract]
string GetStringRepresentationWithComparison(object sourceTarget, object destinationTarget, bool useHtmlMarkup);
}
internal static class MyStringTypeHelper
{
public static IEnumerable<Type> RegisterKnownTypes(ICustomAttributeProvider provider)
{
var files = Directory.GetFiles(@"\\path\to\remote\dlls"); // how can I move the definition of this path to be server side, not client side?
if (files.Length == 0)
return new List<Type>();
var result = new List<Type>();
foreach (var file in files)
{
result.AddRange(Assembly.LoadFile(Path.GetFullPath(file)).GetExportedTypes());
}
return result;
}
}
答案 0 :(得分:0)
您可以使用DataContractResolver
public class SharedTypeResolver : DataContractResolver
{
public override bool TryResolveType(Type dataContractType, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
{
if (!knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace))
{
XmlDictionary dictionary = new XmlDictionary();
typeName = dictionary.Add(dataContractType.FullName);
typeNamespace = dictionary.Add(dataContractType.Assembly.FullName);
}
}
public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
{
return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null) ?? Type.GetType(typeName + ", " + typeNamespace);
}
}
解析器接受您在服务中使用的每种类型。但您必须将解析程序添加到客户端端点和服务器端点。像这样:
Host = new ServiceHost(typeof(MyService));
ContractDescription cd = Host.Description.Endpoints[0].Contract;
foreach (var operation in cd.Operations)
{
operation.Behaviors.Find<DataContractSerializerOperationBehavior>()
.DataContractResolver = new SharedTypeResolver();
}