2011-12-30 5 views
0

J'ai rencontré une exception intéressante. Sur l'un de mes serveurs de production, j'obtiens occasionnellement l'exception suivante.. Exception de référence nulle dans DocumentXPathNavigator

System.NullReferenceException: Object reference not set to an instance of an object. 
    at System.Xml.DocumentXPathNavigator.get_NameTable() 
    at System.Xml.Xsl.Runtime.XmlQueryContext.get_DefaultNameTable() 
    at System.Xml.Xsl.Runtime.XmlQueryRuntime..ctor(XmlQueryStaticData data, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, XmlSequenceWriter seqWrt) 
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results) 
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter) 
    at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results) 
    at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results) 
    at sftControls.SearchListLandingPage.getHtml(IXPathNavigable document, String Xsl, String headerLinks) 

ouverture du IL et en regardant à travers chaque méthode suggère que la DocumentXPathNavigator => this.document est nulle. Ce qui est étrange, c'est que je ne peux en aucun cas dupliquer ce problème localement ou sur nos serveurs de test.

Un peu d'arrière-plan, et cela pourrait être la clé ... Il s'agit d'une application Web (exécutant .Net 3.5) qui met en cache le XmlDocument transmis à XslCompiledTransform.Transform(). Notre mise en cache est assurée par un serveur de cache distribué. Le XmlDocument est sérialisé et mis en cache afin qu'une référence à l'objet spécifique ne puisse pas continuer à exister. Cela me porte à croire que quelque chose empêche explicitement ce.document d'être jamais défini lorsque le XmlDocument -> DocumentXPathNavigator implicite se produit ou qu'une référence quelque part est supprimée pendant que Transform() est en cours d'exécution. De toute façon, je suis perplexe.

Donc, je suppose que mes questions sont les suivantes:

  1. Quelqu'un at-il vu d'autre avant?
  2. Est-ce que quelqu'un sait ce qui pourrait le causer ou comment y faire face?

Merci

EDIT:
Après une réflexion plus poussée à ce sujet, la seule chose qui aurait du sens est que c'est une condition de course. L'appliance de mise en cache expire d'une manière ou d'une autre lorsque l'application utilise l'objet.

EDIT/EDIT:
.Net 3.5, les assembilies référencé ci-dessus sont 2,0

+0

Quelle est la version .NET? –

+0

Il semble que l'entrée est incorrecte. L'avez-vous validé? –

+0

Si vous suivez la trace de la pile, l'entrée est validée avant même qu'elle ne parvienne à ce point. Il est possible que cela change entre quand il est validé et quand il arrive à ce point. – John

Répondre

0

Dans le cas où quelqu'un a cette même exception.

Nous avons constaté que cette exception se produit lorsque xmldocument.HasChildNodes est false ou DocumentElement est null. La vérification que le document contient des éléments, AVANT l'interrogeant, le résout.

0

j'ai vécu une exception très similaire à l'intérieur d'un XslCompiledTransform:

System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.NullReferenceException: Object reference not set to an instance of an object. 
     at MS.Internal.Xml.Cache.XPathDocumentNavigator.get_NodeType() 
     at System.Xml.XPath.XPathNavigator.MoveToNonDescendant() 
     at System.Xml.Xsl.Runtime.DescendantMergeIterator.MoveNext(XPathNavigator input) 
     at <xsl:template name="SystemPartIncluded">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, IList`1 PartNumber, XPathNavigator Description, IList`1 DescriptionOverride, IList`1 Quantity, IList`1 ExtendedPrice, String LabelWhiteSpace) 
     at <xsl:template name="compiler:generated"> (30)(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current, XPathNavigator isBundledWithCanvas, XPathNavigator SoftwareExtendedPrice, XPathNavigator SoftwareUnitPrice, IList`1 PixelNet, IList`1 Revision_Date, IList`1 Catalyst) 
     at <xsl:template name="compiler:generated"> (45)(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current, XPathNavigator SoftwareUnitPrice, XPathNavigator HardwareExtendedPrice, XPathNavigator HardwareUnitPrice, XPathNavigator PixelNetUnitPrice, XPathNavigator FusionUnitPrice) 
     at <xsl:template match="Quote">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current, Double {urn:schemas-microsoft-com:xslt-debug}position, Double {urn:schemas-microsoft-com:xslt-debug}last) 
     at <xsl:template match="/">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current) 
     at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) 
     at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer) 
     at MyApp.clsXML.XslTransformationToHtml(IQEntities DC, Int32 loggedOnUserID, IXPathNavigable input, String xslStylesheetFilePath, XsltArgumentList xslArgs, String XmlRepositoryVersion) in MyApp\App_Data\Static Classes\xml_routines.cs:line 510 
     at MyApp.clsQuote.RenderOneQuote(IQEntities DC, Int32 loggedOnUserID, Int32 quoteID, Boolean booPrintFormat, Boolean booDiscount_Prices, Boolean booIs_Super_Administrator, Boolean isHostRep, String strOrganization_Table_Caption, Boolean showBottomLineOnly) in MyApp\App_Data\Static Classes\quote_routines.cs:line 476 
     at MyApp.Pages.AJAX.BrowseQuotes.RenderSelectedQuote(Int32 quoteID) in MyApp\Pages\AJAX\BrowseQuotes.aspx.cs:line 66 
     at MyApp.Pages.AJAX.BrowseQuotes.ucQuotePicker1_OnQuoteSelectedEvent(Object sender, Int32 quoteID) in b:\DotNet\IQ\WinMetrics.IQ\Pages\AJAX\BrowseQuotes.aspx.cs:line 56 
     at System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) 
     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 
     at System.Web.UI.Page.HandleError(Exception e) 
     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 
     at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 
     at System.Web.UI.Page.ProcessRequest() 
     at System.Web.UI.Page.ProcessRequest(HttpContext context) 
     at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Comme vous, nous passions devant un XPathDocument à la transformation XSL et la XPathDocument est en cours de récupération du cache distribué. Malheureusement, un document XPathDocument n'est pas sérialisable et donc inutilisable après sa récupération dans le cache distribué. Nous avons corrigé le problème en utilisant un XmlDocument au lieu d'un XPathDocument et en utilisant SerializedXmlDocument pour sérialiser et désérialiser comme suit:

 public static XmlDocument CachedXmlDoc 
     { 
      get 
      { 
       lock (_locker) 
       { 
        // maintain the Part XmlDocument in the distributed cache so that it can be reset from any production instance 
        SerializedXmlDocument serializedXmlDoc = Reliable.Application[Global.CACHED_XML_DOC] as SerializedXmlDocument; 
        XmlDocument cachedDoc = (serializedXmlDoc == null) ? null : serializedXmlDoc.XmlDocument; 
        if (cachedDoc == null) 
        { 
         cachedDoc = myController.CreateXmlDoc(); 
         Reliable.Application[Global.CACHED_XML_DOC] = new SerializedXmlDocument(cachedDoc); 
        } 
        return cachedDoc; 
       } 
      } 
      set 
      { 
       lock (_locker) 
       { 
        if (value == null) 
        { 
         Reliable.Application[Global.CACHED_XML_DOC] = null; 
        } 
        else 
        { 
         throw new Exception("Tried to set the cached XmlDocument to something other than null."); 
        } 
       } 
      } 
     } 
Questions connexes