开发者

SharePoint 2010 >> Editing Output HTML >> Issues with page or master page render override

Ok. This is a big one. I'll try and explain my issue but let me know if you need more info.

I would like to alter the HTML that SharePoint 2010 generates. I'm going to use the HTML Agility Pack] which will take a string of HTML among other objects and alter the source.

There are 2 ways of altering the full source in SP.

  1. Using Control Adapters, or Extending Controls I can access the Page, MasterPage or even ContentPlaceHolder render methods, grab the HTML, Alter it and then write it.
  2. Use a HTTP Module with a filter and alter the output stream

Unfortunately there are issues with both of these methods.

Number 2, the filter works good but you have to disable the Output Cache. I can't do this. The sites I brand have massive amounts of traffic. So filters are moot until the SharePoint 2010 team fixes / presents us with a workaround. I read somewhere in my travels they are aware and will be doing something about it.

Number 1 works great. I simply use the following and I can alter the HTML of the page but there is one big problem.

HtmlDocument hd    = new HtmlDocument(); //Agility HTML Object.
StringBuilder sb   = new StringBuilder();
StringWriter sw    = new StringWriter(sb);
HtmlTextWriter htw = new HtmlTextWriter(sw);

//Render Object into HtmlTextWriter
base.Render(htw);

//String to hold the HTML from the StringBuilder of the HtmlTextWriter
string html = sb.ToString();

//Mess with the String here using the Agility HTML Pack

//Write the HTML to the writer
writer.Write(html);

//Done!

This code works great, but SharePoint 2010 is appending data to the writer / or altering controls after the render override for the Page / MasterPage.

When i debug and walk-through and look at the html string it look like the following.

"<html ....  ....</html>"

This is important to note because there is nothing before the first HTML tag. The Opening "&l开发者_开发问答t;" is in position 0.

But when the HTML ends up in the browser I see the following.

DOMAIN\user<script type="text/javascript">
//<![CDATA[
var _spUserId=1;
//]]>
</script>
<html... 
....</html>

Also the user name is missing from the welcome area in the top right of the ribbon because it's now putting it up before the opening tag.

If I don't assign the writer object anything in the render override the page in the browser just shows everything before the HTML tag. The funny thing is it shouldn't show anything!

If I visit other pages. ANY page that has a list view. All of the items are rendered before tag. It's important to note that it's just the Values, not the html. The HTML for the list items exists where it should down in the list view.

For Example. (Page is "/_layouts/viewlsts.aspx" )

Without the render override.

<html...

...
//The Table where the data should be.
<tr>
    <td class="ms-gb"  colspan="5" style="white-space:nowrap;">
        <h3 class="ms-standardheader">
            &#160; Picture Libraries
        </h3>

    </td>
</tr>

<tr><td class="ms-vb2 ms-viewlsts-noitems" colspan="6">
    There are no picture libraries. To create one, click <b>Create</b> above.
</td></tr>

<tr>
    <td class="ms-gb"  colspan="5" style="white-space:nowrap;">
        <h3 class="ms-standardheader">

            &#160; Lists
        </h3>
    </td>
</tr>

<tr><td class="ms-vb2 ms-viewlsts-noitems" colspan="6">
    There are no lists. To create one, click <b>Create</b> above.
</td></tr>

<tr>

    <td class="ms-gb"  colspan="5" style="white-space:nowrap;">
        <h3 class="ms-standardheader">
            &#160; Discussion Boards
        </h3>
    </td>
</tr>

<tr class="ms-alternatingstrong">
    <td class="ms-vb-icon">

            <a id="viewlistDiscussionBoard" href="/Lists/Discussion%20Board/AllItems.aspx" >

            <img border="0" alt="Discussion Board" src="/_layouts/images/itdisc.png" width="16" height="16" /></a>
    </td>
    <td class="ms-vb2" >
            <a id="viewlistDiscussionBoard" href="/Lists/Discussion%20Board/AllItems.aspx">Discussion Board</a>&#160;
    </td>

    <td class="ms-vb2" width="40%" >
            &#160;
    </td>

    <td class="ms-vb2" width="3%" align="right">
    1
    </td>
    <td class="ms-vb2" width="25%" >
        <nobr>
        3 days ago
        </nobr>
    </td>
</tr>
...</html>

With the render override.

DOMAIN\user<script type="text/javascript">
//<![CDATA[
var _spUserId=1;
//]]>
</script>Document Libraries"viewlistDocumentLibrary""/AnalyticsReports/Forms/AllItems.aspx""Customized Reports""/_layouts/images/itdl.png""viewlistDocumentLibrary""/AnalyticsReports/Forms/AllItems.aspx"Customized ReportsThis Document library has the templates to create Web Analytics custom reports for this site collection04 days ago"viewlistDocumentLibrary""/Style%20Library/Forms/AllItems.aspx""Style Library""/_layouts/images/itdl.png""viewlistDocumentLibrary""/Style%20Library/Forms/AllItems.aspx"Style LibraryUse the style library to store style sheets, such as CSS or XSL files. The style sheets in this gallery can be used by this site or any of its subsites.04 days agoPicture LibrariesThere are no picture libraries. To create one, click <b>Create</b> above.ListsThere are no lists. To create one, click <b>Create</b> above.Discussion Boards"viewlistDiscussionBoard""/Lists/Discussion%20Board/AllItems.aspx""Discussion Board""/_layouts/images/itdisc.png""viewlistDiscussionBoard""/Lists/Discussion%20Board/AllItems.aspx"Discussion Board13 days agoSurveysThere are no surveys. To create one, click <b>Create</b> above.Blog0
<html...

//The Table where the data should be.
...
<tr>
    <td class="ms-gb"  colspan="5" style="white-space:nowrap;">
        <h3 class="ms-standardheader">

            &#160; 
        </h3>
    </td>
</tr>

<tr><td class="ms-vb2 ms-viewlsts-noitems" colspan="6">

</td></tr>

<tr>
    <td class="ms-gb"  colspan="5" style="white-space:nowrap;">
        <h3 class="ms-standardheader">

            &#160; 
        </h3>
    </td>
</tr>

<tr class="ms-alternatingstrong">
    <td class="ms-vb-icon">

            <a id= href= >
            <img border="0" alt= src= width="16" height="16" /></a>
    </td>

    <td class="ms-vb2" >
            <a id= href=></a>&#160;
    </td>

    <td class="ms-vb2" width="40%" >
            &#160;
    </td>
    <td class="ms-vb2" width="3%" align="right">

    </td>
    <td class="ms-vb2" width="25%" >

        <nobr>

        </nobr>
    </td>
</tr>
... </html>

My guess is it has something to do with resource files..

Whatever the case it's obvious that there is some sort of manipulation of the objects after the Page or MasterPage render methods. I just can't find it.

My HTTP Module filter stream has the HTML in the proper place.. So somewhere between the Page render and sending the HTML to the browser there is something going on.

Here are a couple of other people reporting the same issue without any useful responses.

  1. Link 1
  2. Link 2

I would appreciate any insight on this! THANKS!


The problem is caused by something in the page interfering with the outputcache during render, and more specifically the behaviour of the PostCacheSubstitutionTextHelper class. Probably your call to Render above triggers this.

The welcome.asxc control behaves approximately like this (pseudo sequence diagram):

Page Render > Welcome.ascx Render > PersonalActions Render > PostCacheSubstitutionText.Render > PostCacheSubstitutionTextHelper.RenderAndRegisterSubstitutionCallbackHandler (new instance of)PostCacheSubstitutionText.Render(called in delegate and now writes to HtmlTextWriter) > PostCacheSubstitutionTextHelper. RenderAndRegisterSubstitutionCallbackHandler HttpContext.Response.WriteSubstitution(stuffFromNewInstanceOfPostCacheSubstitutionText)

So enough with the sharepoint freakshow and over to the workaround:-)

Try adding this to your welcome.ascx in the hive:

// in bottom of directives in /CONTROLTEMPLATES/Welcome.ascx
<%@ OutputCache Duration="1" VaryByParam="none" %>

Notice that the Duration is set to 1 since 0 is not allowed for user controls. this leaves a theoretical possiblity for failure, but in our scenario it worked.


I ran into this same problem, I was able to workaround the issue by removing this line from the masterpage.

<wssuc:Welcome id="IdWelcome" runat="server">
</wssuc:Welcome>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜