序列化对象的XmlDocument [英] Serialize object to XmlDocument

查看:261
本文介绍了序列化对象的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆