Pour retourner des informations utiles dans SoapException.Detail
pour un service Web asmx, j'ai pris une idée de WCF et créé une classe de panne pour contenir lesdites informations utiles. Cet objet d'erreur est ensuite sérialisé au XmlNode
requis d'un SoapException
levé.Sérialiser l'objet à XmlDocument
Je me demande si j'ai le meilleur code pour créer la XmlDocument
- voici mon avis sur la question:
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);
}
Y at-il une meilleure façon de le faire?
MISE À JOUR: J'ai fini par faire ce qui suit, parce que si vous enroulez le XML dans un élément <detail>
xml, vous obtenez un SoapHeaderException
à la fin du client:
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);
MISE À JOUR 2: Étant donné John Saunders excellente réponse, je l'ai maintenant commencé à utiliser les éléments suivants:
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();
}
J'ai mis à jour mon code postal pour l'élément de détail. –
dans l'ensemble ça me semble bien, même si je pense que j'utiliserais des objets fortement typés plutôt que des vars dans ce cas. En outre, je ne sais pas que 'stream.Seak (0, SeekOrigin.Begin)' est vraiment nécessaire. – CodeMonkey1313