Rendering xhtml data from within an asp.net usercontrol

Topics: General, MVC, XSLT
Jan 26, 2011 at 3:14 PM

What is the best way to render an xhtml field from within a usercontrol?

Example:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="topicoverviewcontrol.ascx.cs" Inherits="frontend_iihs_research_topicoverviewcontrol" %>
<%@ Register Src="~/frontend/iihs/research/topicsmenu.ascx" TagPrefix="iihs" TagName="TopicsMenu" %>

<div>
    <IIHS:TopicsMenu runat="server" TopicMenu='<%# this.ViewModel.Menu %>' />
</div>

<h2><%# this.ViewModel.Tag.TagName %></h2>
<%# this.ViewModel.Content %>
The above this.ViewModel.Content is an xhtml document string stored in a composite data type.
Thanks,
Peter
Coordinator
Jan 26, 2011 at 4:25 PM

ASP.NET Web Form execute after Composite C1 has constructed the page so the you are in control at this point (the time for normalization of nested xhtml documents that the Composite C1 rendering engine does for xslt, mvc, etc. has passed).

If ViewModel.Content is maintained by the visual html editor inside the C1 Console this will contain a complete xhtml document - in that case you should strip away anything but the content of the body element.

If you never expect users to actually put anything into the <head /> section of that particular content I expect the best performing way would be to locate "<body>" and "</body>" inside this string, and then grab the substring in between.

 

 

Jan 26, 2011 at 6:50 PM

Thanks for you help and I can see that this would work, but users would lose the ability to use functions within their content.  Isn't their someway I could within code send the content through a similar process that a page goes through to get rendered thus allowing things like xslt functions to be processed.

Jan 26, 2011 at 7:03 PM

If you want to be able to parse the content of the xml and any functions it might contain, you can have a look in the Contrib-project, to see how we for instance handle masterpages. The code you would be interested in is the following

var doc = XElement.Parse(YOUR_XML_AS_STRING);
var context = PageRenderer.GetPageRenderFunctionContextContainer();

PageRenderer.ExecuteEmbeddedFunctions(doc, context);

var mi = typeof(PageRenderer).GetMethod("NormalizeXhtmlDocument", BindingFlags.Static | BindingFlags.NonPublic);
mi.Invoke(null, new[] { new XhtmlDocument(doc) });

var body = doc.Descendants().Single(el => el.Name.LocalName == "body");
var c = body.AsAspNetControl((IXElementToControlMapper)context.XEmbedableMapper);
Now you can take c and insert it into your Usercontrol or some placeholder or whatever.

Coordinator
Jan 26, 2011 at 9:34 PM

@pedwards You could also render using XSLT or MVC Razor (check the second View example at http://community.composite.net/C1/Blog.aspx/2011/01/25/Listdetail-views-with-MVC-3-and-AJAX - it outputs a 'xhtml content' will will be handled as you desire ). Or the code above to stick with Web Forms.

Jan 26, 2011 at 9:43 PM

Returning xhtml that again contains C1 functions from a MVC player will still yield in the same problem that pedwards has at the moment, no?

Coordinator
Jan 26, 2011 at 9:46 PM

The MvcPlayer is a C1 Function and all output from C1 Functions during a page rendering will be parsed for nested function calls etc. - so it works :-)

Jan 27, 2011 at 3:45 PM

Both these options are great.  Thanks.