2009-04-23 81 views
14

为了在SoapException.Detail返回有用信息的ASMX Web服务,我把一个想法从WCF并创建了一个故障类包含说有用的信息。然后,该故障对象序列化到一个抛出SoapException所需XmlNode序列化对象的XmlDocument

我不知道我是否有创造最佳的代码XmlDocument - 这是我对此采取:

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); 
} 

是否有这样做的更好的办法?

更新:其实我结束了做以下,因为除非你包的XML在<detail> XML元素,你在客户端得到一个SoapHeaderException

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); 

更新2:鉴于约翰·桑德斯出色答卷,我现在已经开始使用下列内容:

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(); 
} 
+0

我更新了我的细节元素的邮政编码。 – 2009-04-23 18:17:01

+0

整体看起来对我好,但我想我会使用强类型的对象,而不是瓦尔在这种情况下。另外,我不知道`stream.Seak(0,SeekOrigin.Begin)`是非常必要的。 – CodeMonkey1313 2009-04-23 12:18:48

回答

18

编辑:创建OUTP ut里面的细节元素

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; 
}