Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile error CS1647 when opening large aspx file in browser

I am using XML/XSLT to create an aspx page which can grow quite large. Even though the file is successfully created, when the file size approaches 300K, the error: “CS1647: An expression is too long or complex to compile” is issued when opening the file in a browser (tried both IE and Chrome). No other useful information is shown on the failed .NET error page.

My development environment is VS 2012 Express for Web on a Win7 x64 laptop.

Since this problem does not occur during the execution of the program, I am at a loss as to how to approach solving this problem. Can anyone suggest a strategy or work around to this issue?

EDIT

The C# code used to create the aspx page is

// load the xml file
XmlDocument reportDetails = new XmlDocument();
reportDetails.Load(ReportDetailsPath);
//setup the xslt transform
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XlsRptPath);
StringWriter sw = new StringWriter();
xslt.Transform(ReportDetails, null, sw);
//create the aspx file
using (StreamWriter outfile = new StreamWriter(aspxPath))
{
    outfile.Write(sw.ToString());
}
like image 333
ron tornambe Avatar asked Jan 06 '13 17:01

ron tornambe


2 Answers

Old question, and largely answered in the comments. But for the sake of completeness, let's answer it ;). Your issue is not with XSLT itself, but with the generated file which hits the 300k boundary of maximum expression size in C#. There are a couple of things you can do:

  • Make the generated code below 300k (but this might not be possible in your case)
  • Take any string constants in the generated code and place them in a resource file. The format of such resource files is XML and you can auto-generate it, just make sure the IDs in the resource match the IDs you use in the generated ASPX
  • Place part of the generated code in a code-behind file. An ASPX is parsed as one expression, but the code-behind is not. This is a matter of structuring the generated code.
  • Split the ASPX in multiple pages, if your design allows this. You can recombine them with iframes.
  • Split the ASPX file in multiple ASCX controls. This is perhaps the most natural thing to do. Each ASCX control can be referenced/added to the ASPX file. Each ASCX control should not exceed the 300k limit.
  • If there is a lot of generated CSS that blows up the size, place it in a separate CSS file.
  • If there are a lot of long absolute paths in image references and the like, you can collapse them and make the references relative, i.e. by using <base>, which may save you some space.
  • If the error is caused by actual large (constant) expressions, consider the hints in the answers in this post for a resolution.
like image 135
Abel Avatar answered Sep 30 '22 21:09

Abel


I am sorry for not posting my solution sooner, but I was too stressed at the time to do so. Better late than never I guess.

Instead of trying to create a complete aspx web page for each associated xml file, I created a stub and applied the xslt transform at run-time from within an associated Site.Master. The stub's MasterPageFile property is set to this Site.Master. This approach does sacrifice some performance, but it works for any size web page. Here is an example of the outputted webpage.

Example aspx stub file:

<%@ Page Title="Top Austin Beauty Salons List" MetaDescription="List of best Google-ranked Austin beauty salon" Language="C#" MasterPageFile="~/Site1.Master" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
</asp:Content>

Site.Master Page_Load:

    protected void Page_Load(object sender, EventArgs e)
    {
        string vp =  Page.AppRelativeVirtualPath;
        if (vp.ToLower().EndsWith("default.aspx") || vp.ToLower().EndsWith("webform2.aspx")) return; // ignore some aspx files used for ohter reasons
        string xmlPath = Page.MapPath(vp.Substring(0, vp.LastIndexOf(".")) + @".xml");
        string xslPath = Page.MapPath("mainpage.xslt");
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(xmlPath);
        XsltArgumentList argsList = new XsltArgumentList();
        argsList.AddParam("xmlPath", "", xmlPath);

        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load(xslPath);
        // Execute the transform and output the results to a string writer.
        StringWriter sw = new StringWriter();
        xslt.Transform(xmlDoc, argsList, sw);
        content.InnerHtml = sw.ToString(); // add the generated html to the associated stub aspx content section
    }
like image 29
ron tornambe Avatar answered Sep 30 '22 20:09

ron tornambe