序列化对象的XmlDocument [英] Serialize object to XmlDocument
问题描述
为了返回 SoapException.Detail
有用的信息,为ASMX web服务,我从WCF的想法,并创建了一个故障类含有该有用的信息。断层对象被序列化到所需的的XmlNode
的抛出的SoapException
。
我不知道是否我有最好的code创建的XmlDocument
- 这里是我对吧:
VAR的XmlDocument =新的XmlDocument();
VAR串行器=新的XmlSerializer(typeof运算(T));
使用(VAR流=新的MemoryStream())
{
serializer.Serialize(流theObjectContainingUsefulInformation);
stream.Flush();
stream.Seek(0,SeekOrigin.Begin); XMLDocument.load方法(流);
}
是否有这样做的更好的办法?
更新:其实我最终执行以下操作,因为除非你包在&LT XML的代码;详情>
XML元素,你会得到一个 SoapHeaderException
在客户端为:
VAR serialiseToDocument =新的XmlDocument();
VAR串行器=新的XmlSerializer(typeof运算(T));
使用(VAR流=新的MemoryStream())
{
serializer.Serialize(流e.ExceptionContext);
stream.Flush();
stream.Seek(0,SeekOrigin.Begin); serialiseToDocument.Load(流);
}//删除XML声明
serialiseToDocument.RemoveChild(serialiseToDocument.FirstChild);//记着我们希望节点
VAR serialisedNode = serialiseToDocument.FirstChild;//,敷在<详情>元件
VAR rootNode中= serialiseToDocument.CreateNode(XmlNodeType.Element,细节,);
rootNode.AppendChild(serialisedNode);
更新2:由于约翰·桑德斯出色答卷,我现在已经开始使用下列内容:
私有静态无效SerialiseFaultDetail()
{
VAR值=新ServiceFault
{
消息=异常发生
错误code = 1010
}; //序列化到XML文档
VAR detailDocument =新的XmlDocument();
VAR NAV = detailDocument.CreateNavigator(); 如果(NAV!= NULL)
{
使用(XmlWriter的作家= nav.AppendChild())
{
VAR SER =新的XmlSerializer(fault.GetType());
ser.Serialize(作家,故障);
}
} //记着并删除我们想要的元素
XmlNode的infoNode = detailDocument.FirstChild;
detailDocument.RemoveChild(infoNode); //移动到根<详情>元件
VAR rootNode中= detailDocument.AppendChild(detailDocument.CreateNode(XmlNodeType.Element,细节,));
rootNode.AppendChild(infoNode); Console.WriteLine(detailDocument.OuterXml);
Console.ReadKey();
}
编辑:创建细节元素中输出
公共类MyFault
{
公众诠释错误code {搞定;组; }
公共字符串的ErrorMessage {搞定;组; }
}公共静态的XmlDocument SerializeFault()
{
VAR值=新MyFault
{
错误code = 1,
的ErrorMessage =这是一个错误
}; VAR faultDocument =新的XmlDocument();
VAR NAV = faultDocument.CreateNavigator();
使用(VAR作家= nav.AppendChild())
{
VAR SER =新的XmlSerializer(fault.GetType());
ser.Serialize(作家,故障);
} VAR detailDocument =新的XmlDocument();
VAR detailElement = detailDocument.CreateElement(
EXC
SoapException.DetailElementName.Name,
SoapException.DetailElementName.Namespace);
detailDocument.AppendChild(detailElement);
detailElement.AppendChild(
detailDocument.ImportNode(
faultDocument.DocumentElement,真));
返回detailDocument;
}
In order to return useful information in SoapException.Detail
for an asmx web service, I took an idea from WCF and created a fault class to contain said useful information. That fault object is then serialised to the required XmlNode
of a thrown SoapException
.
I'm wondering whether I have the best code to create the XmlDocument
- here is my take on it:
var xmlDocument = new XmlDocument();
var serializer = new XmlSerializer(typeof(T));
using (var stream = new MemoryStream())
{
serializer.Serialize(stream, theObjectContainingUsefulInformation);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
xmlDocument.Load(stream);
}
Is there a better way of doing this?
UPDATE: I actually ended up doing the following, because unless you wrap the XML in a <detail>
xml element, you get a SoapHeaderException
at the client end:
var serialiseToDocument = new XmlDocument();
var serializer = new XmlSerializer(typeof(T));
using (var stream = new MemoryStream())
{
serializer.Serialize(stream, e.ExceptionContext);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
serialiseToDocument.Load(stream);
}
// Remove the xml declaration
serialiseToDocument.RemoveChild(serialiseToDocument.FirstChild);
// Memorise the node we want
var serialisedNode = serialiseToDocument.FirstChild;
// and wrap it in a <detail> element
var rootNode = serialiseToDocument.CreateNode(XmlNodeType.Element, "detail", "");
rootNode.AppendChild(serialisedNode);
UPDATE 2: Given John Saunders excellent answer, I've now started using the following:
private static void SerialiseFaultDetail()
{
var fault = new ServiceFault
{
Message = "Exception occurred",
ErrorCode = 1010
};
// Serialise to the XML document
var detailDocument = new XmlDocument();
var nav = detailDocument.CreateNavigator();
if (nav != null)
{
using (XmlWriter writer = nav.AppendChild())
{
var ser = new XmlSerializer(fault.GetType());
ser.Serialize(writer, fault);
}
}
// Memorise and remove the element we want
XmlNode infoNode = detailDocument.FirstChild;
detailDocument.RemoveChild(infoNode);
// Move into a root <detail> element
var rootNode = detailDocument.AppendChild(detailDocument.CreateNode(XmlNodeType.Element, "detail", ""));
rootNode.AppendChild(infoNode);
Console.WriteLine(detailDocument.OuterXml);
Console.ReadKey();
}
EDIT: Creates output inside of detail element
public class MyFault
{
public int ErrorCode { get; set; }
public string ErrorMessage { get; set; }
}
public static XmlDocument SerializeFault()
{
var fault = new MyFault
{
ErrorCode = 1,
ErrorMessage = "This is an error"
};
var faultDocument = new XmlDocument();
var nav = faultDocument.CreateNavigator();
using (var writer = nav.AppendChild())
{
var ser = new XmlSerializer(fault.GetType());
ser.Serialize(writer, fault);
}
var detailDocument = new XmlDocument();
var detailElement = detailDocument.CreateElement(
"exc",
SoapException.DetailElementName.Name,
SoapException.DetailElementName.Namespace);
detailDocument.AppendChild(detailElement);
detailElement.AppendChild(
detailDocument.ImportNode(
faultDocument.DocumentElement, true));
return detailDocument;
}
这篇关于序列化对象的XmlDocument的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!