0

I am working on an older project using .NET framework 4.5. There is an aspx page with an OnSelectedIndexChanged event that completes via a server side call. The server side call uses a stored proc that returns xml and then uses a transformation to convert the xml into html. The issue is that when the xml is large (currently testing with 10k records in xml format from the stored proc though the expectation is 100k records in production), then the aspx page times out. I am not sure what the best way to fix this issue is since the web.config settings for executionTimeout is set very high and debug is set to false.

Web.Config

<httpRuntime maxRequestLength="102400" executionTimeout="20000"/>

ASPX Page

<asp:DropDownList ID="ddlViews" runat="server" AutoPostBack="true" style="height:25px;min-width:150px;"  
    OnSelectedIndexChanged="ddlViews_SelectedIndexChanged">
</asp:DropDownList>

. . .

<asp:UpdatePanel ID="updPnl" runat="server">
    <Triggers> 
        <asp:AsyncPostBackTrigger ControlID="ddlViews" EventName="SelectedIndexChanged" />
     </Triggers>
    <ContentTemplate>
        <asp:Literal ID="litData" runat="server"></asp:Literal>
    </ContentTemplate>
</asp:UpdatePanel>

ASPX Code Behind

protected void ddlViews_SelectedIndexChanged(object sender, EventArgs e)
{
    if (ddlViews.Items.Count > 0 && ddlViews.SelectedValue != "-1")
    {
        System.Threading.Thread.Sleep(3000);
        ShowView();
    }
}

private void ShowView()
{
    if (ddlViews.Items.Count > 0)
    {
        string inputXml = GetXml();
        strData = Utils.ApplyXslt(inputXml);

        litData.Text = strData;
    }
}

public static string ApplyXslt(string xml)
{
    try
    {
        string xsltUri = GetXslPath();
        XsltArgumentList xslArg = new XsltArgumentList();
        xslArg.AddExtensionObject("urn:string-plus", new XslStringPlus());
        var xdoc = new XmlDocument();
        xdoc.LoadXml(xml);
        var xslt = new System.Xml.Xsl.XslCompiledTransform();

        using (var mStream = new System.IO.MemoryStream())
        {
            xslt.Load(xsltUri);
            xslt.Transform(xdoc, xslArg, mStream);
            mStream.Position = 3;
            var sr = new System.IO.StreamReader(mStream);
            return sr.ReadToEnd();
        }
    }
    catch (Exception e){
        throw new Exception(String.Format("Error Applying Xslt from path '{0}'to xml value '{1}'", xsltUri, xml) + " | " + e.StackTrace);
    }
}

The Transform is taking close to 3 minutes to complete for 10k records. It would be great to be able to drastically reduce that time if possible. The page is timing out after 1.5 minutes and I cannot find anything that works to increase that.

XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xslplus="urn:string-plus">
    <xsl:output method="html" />
    <xsl:template match="/">
        <table  id="tblLoanQuery" class="tableStyle">
            <tr>
                <xsl:for-each select="ROOT/Fields/child::*">
          <xsl:variable name="h" select="." />
                    <th><xsl:value-of select="xslplus:FormatLabel($h)" /></th>
                </xsl:for-each>
            </tr>
            <xsl:for-each select="ROOT/LoanNumbers/child::*">
                <xsl:variable name="loanId" select="." />
                <tr>
                    <xsl:for-each select="//ROOT/Fields/Field">
                        <xsl:variable name="fullFieldName" select="." />
                        <xsl:variable name="field" select="substring-after($fullFieldName,'.')" />
            <xsl:variable name="FieldValue" select="//ROOT/ROWS/row[@lqKey=$loanId]/@*[name(.)= xslplus:ConvertSpace($field)]/." />
            <td>
              <xsl:value-of select="xslplus:FormatValue($FieldValue)"/>              
            </td>
                    </xsl:for-each>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>
1
  • Dos the XSLT differ on each call? If not, consider to precompile (with xsltc) and cache the XslCompiledTransform instance if the ASP.NET framework allows that. Commented Apr 9, 2020 at 10:41

1 Answer 1

1

In terms of XSLT it appears that //ROOT/ROWS/row[@lqKey=$loanId] suggests you want to use a key <xsl:key name="row-ref" match="ROOT/ROWS/row" use="@lqKey"/> and use key('row-ref', $loanId) instead of //ROOT/ROWS/row[@lqKey=$loanId]. The use of a key might improve run-time performance.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Martin Honnen! The XLST now runs in about 20 seconds for 10k records.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.