【发布时间】:2012-11-21 14:15:21
【问题描述】:
我们从 WCF Web 服务返回 AuthenticateUserOutput 类的实例。
所以我们有这个方法:
public override AuthenticateUserOutput AuthenticateUser(AuthenticateUserInput AuthenticateUserInput)
AuthencateUserOutput 是自动生成的:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.5420")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="xxxx")]
public partial class AuthenticateUserOutput : WS2MethodOutput
{
private bool authenticationResultField;
private UserContext userContextField;
/// <remarks/>
public bool AuthenticationResult
{
get
{
return this.authenticationResultField;
}
set
{
this.authenticationResultField = value;
}
}
/// <remarks/>
public UserContext UserContext
{
get
{
return this.userContextField;
}
set
{
this.userContextField = value;
}
}
}
我们需要能够反序列化为AuthenticateUserOutput,但它不起作用。
作为测试,我实例化了一个AuthenticateUserOutput,将其序列化并尝试反序列化。
InvalidOperationException 失败。
这是序列化的 Xml:
<?xml version="1.0" encoding="utf-16"?>
<AuthenticateUserOutput xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="xxxx">
<Response xmlns="xxxx">
<IsValid>true</IsValid>
<Success>true</Success>
</Response>
<AuthenticationResult xmlns="xxxx">true</AuthenticationResult>
<UserContext xmlns="xxxx">
</UserContext>
</AuthenticateUserOutput>
下面是序列化和反序列化代码:
public static string ToXml(this object input)
{
string output;
XmlSerializer serializer = new XmlSerializer(input.GetType());
StringBuilder sb = new StringBuilder();
using (TextWriter textWriter = new StringWriter(sb))
{
serializer.Serialize(textWriter, input);
}
output = sb.ToString();
return output;
}
还有:
public static T FromXml<T>(this string input)
{
T output;
XmlSerializer serializer = new XmlSerializer(typeof(T));
output = (T)serializer.Deserialize(new StringReader(input));
return output;
}
异常的具体细节:
System.InvalidOperationException occurred
Message="<AuthenticateUserOutput xmlns='xxxx'> was not expected."
Source="qkxd8dd-"
StackTrace:
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAuthenticateUserOutput.Read31_AuthenticateUserOutput()
InnerException:
所以它不能反序列化它自己的序列化 Xml。
有人知道为什么吗?
谢谢,
J1M.
更新:这是测试代码:
AuthenticateUserOutput test = new AuthenticateUserOutput();
test.AuthenticationResult = true;
test.Response = new ResponseType();
test.Response.Exception = null;
test.Response.IsValid = true;
test.Response.Success = true;
test.Response.ValidationErrors = null;
test.UserContext = new UserContext();
string serializedXml = test.ToXml();
AuthenticateUserOutput deserializedString = serializedXml.FromXml<AuthenticateUserOutput>();
UPDATE2:感谢 Mark Gravell,反序列化器的工作原理
OK, I forgot I'd added this to get the namespaces to come out correctly when de-serializing:
public partial class WS2MethodInput
{
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces _xmlns;
/// <summary>
/// Constructor for WS2MethodInput that sets up default namespaces
/// </summary>
public WS2MethodInput()
{
_xmlns = new XmlSerializerNamespaces();
_xmlns.Add("", "xxxx");
}
}
这样,序列化的 Xml 就像它在此消息的顶部一样。 没有它,反序列化程序可以工作,但 AuthenticateUserOutput 缺少命名空间:
<?xml version="1.0" encoding="utf-16"?>
<AuthenticateUserOutput xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="xxxx">
<Response xmlns="xxxx">
<IsValid>true</IsValid>
<Success>true</Success>
</Response>
<AuthenticationResult xmlns="xxxx">true</AuthenticationResult>
<UserContext xmlns="xxxx">
</UserContext>
</AuthenticateUserOutput>
注意AuthenticateUserOutput末尾的xmlns="xxxx"
问题是,现在我不能在没有其他代码的情况下将该 Xml 与我们的其他代码一起使用:
1) 将其加载到 XDocument 中并添加命名空间并在需要反序列化时将其删除 2)对正则表达式的字符串替换或其他东西做同样的事情
这两个我都不喜欢。事实上,这太可怕了! 8X
【问题讨论】:
-
T到FromXml是什么,原始对象的GetType()是什么?它们是一样的吗? -
我将添加测试代码,T 是 AuthenticateUserOutput。我会为很多方法这样做,所以我从编写 To/From Xml 扩展开始
-
哦,是的,typeof(T) == input.GetType()
-
你的测试代码基本上对我有用;我不得不稍微调整一下才能让它编译(添加一些类,删除响应)
-
谢谢,这让我可以开始工作了。我弄清楚了原因,我将在帖子中添加更多内容。然而,问题是由我添加并忘记发布的另一个问题的解决方案引起的。但是,如果我删除该解决方案,另一个问题又回来了。忍受我。
标签: c# xmlserializer invalidoperationexception