这让我发疯了...我正在尝试拥有一个源自System.IdentityModel.Tokens.SecurityToken
的自定义WCF身份验证令牌,例如:
public class TestSecurityToken : SecurityToken
{
public override string Id
{ get { return "123"; } }
public override ReadOnlyCollection<SecurityKey> SecurityKeys
{ get { return new ReadOnlyCollection<SecurityKey>(new List<SecurityKey>(0)); } }
public override DateTime ValidFrom
{ get { return DateTime.MinValue; } }
public override DateTime ValidTo
{get { return DateTime.MaxValue; } }
public string Property1 { get; set; }
}
我知道我可以为它扩展WSSecurityTokenSerializer
编写一个自定义序列化程序,但我试图找到一种方法以通用方式执行此操作,我可以创建一个可以序列化任何{{1 }}
这是我尝试过的,但失败了:
尝试1 :将SecurityToken设为DataContract
<T> where T : SecurityToken
失败,因为您无法从不是DataContract的基类派生DataContract,而SecurityToken则不是。
尝试2 :使用XmlSerializer序列化
[DataContract]
public class TestSecurityToken : SecurityToken
失败并显示错误:
System.InvalidOperationException:出现反映类型'PartsSource.Services.Core.ServiceModel.SecurityTokenSerializerTest.TestSecurityToken'的错误。 ---&GT; System.InvalidOperationException:要进行XML可序列化,从ICollection继承的类型必须在其继承层次结构的所有级别都具有Add(System.IdentityModel.Tokens.SecurityKey)的实现。 System.Collections.ObjectModel.ReadOnlyCollection`1 [[System.IdentityModel.Tokens.SecurityKey,System.IdentityModel,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]未实现Add(System.IdentityModel.Tokens.SecurityKey) )。
由于我的自定义public class SecurityTokenSerializer<T> : WSSecurityTokenSerializer where T : SecurityToken
{
private readonly XmlSerializer serializer;
public SecurityTokenSerializer()
{
serializer = new XmlSerializer(typeof (T));
}
protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)
{
serializer.Serialize(writer, token);
}
上的此属性:
SecurityToken
尝试3 :与上述相同,但尝试告诉XmlSerializer忽略SecurityKeys属性:
public override ReadOnlyCollection<SecurityKey> SecurityKeys
{ get { return new ReadOnlyCollection<SecurityKey>(new List<SecurityKey>(0)); } }
此错误与前一次尝试的消息相同。它不会忽略这个属性。
有没有人对如何将任何SecurityToken序列化为XmlReader / XmlWriter有任何其他想法?看起来应该已经死了简单,但没有......
答案 0 :(得分:0)
由于我没有找到其他好方法,我最终做的是让我的自定义SecurityToken也实现IXmlSerializable
,然后将我的序列化程序的定义更改为:
public class SecurityTokenSerializer<T> : WSSecurityTokenSerializer
where T : SecurityToken, IXmlSerializable
我的自定义安全令牌定义为:
public class MySecurityToken : SecurityToken, IXmlSerializable
然后,序列化程序可以将序列化委派给自定义安全令牌。它可能不是最干净的解决方案(我说它违反了单一责任主体),但它确实有效,让我不必为每个自定义令牌编写序列化器。