views:

1167

answers:

6

We have bunch of Domain Entities which should be rendered to an html format, which shows their detail in a pop up window.

I would be glad to do something like this:

Product product = new Product(...);
product.ToHtml();  // or: HtmlRenderer.Render(Product);

but my main problem is how to do this stuff from behind. I have 3 different answers:

1. Render By Code:

I can simply write my code for rendering the Html inside the ToHtml Method (C#) - the problem it is that it is too static. if you would like to move a little bit the header to the middle you should change code. moreover, it is very hard to read Html indentation in C#.

2. Using XSL:

XSL Files can easily manage the Html template and using XSLT I can transform XML file to the right place of the documents. the parser already written by someone else (just need to learn the syntax) ** for this we will need that each object could serialize to Xml. and if the object changed -> the Xml will be changed --> the xslt need to be changed too ** this will also give me the option to indent the html easily for example: adding css capabilities and\or change the html design

3. using other template engine:

Write my own C# -> Html template Engine so it will read the template from file (*.template) and will insert the right property in the right place of the template using reflection. ** in this solution we have many issues that we can think of, for example: how the syntax should be like? is this thing ok? %Name% %Description% and how we can handle arrays? ** maybe we can use an existing engine (Brail or T4-Templating)?

What do you prefer? do you know a good engine? for now I prefer the second solution, but it gonna be very slow.

thanks

+3  A: 

This is the job of your view, not your controllers or models. As you suspect, using method (1) will make your changes very brittle. Instead, write a view fragment for each way in which you'd like to render a particular domain entity. Then simply pull in the appropriate views to build your final page.

John Feminella
+2  A: 

I sincerely prefer method A. The HTML is already a standard so you shouldn't beat yourself up too much with intermediary formats such as XML (via XSL - method 2) or a custom format (method 3).

If writing in/for ASP.NET MVC you could however build an .ASCX (user control) that would accept an object of your type and render the appropiate HTML. And you don't get the nasty C# indentation and no highlighting nor autocomplete.

You could also write multiple User views to accomodate different scenarios for one object type.

Andrei Rinea
I am not working in a web team, I am rendering objects-as-html and send them to anyone else - who can use this in wpf\palm\web-site or other technology, so I guess ascx is not good for me.
rabashani
shahkalpesh
still not good enough I want them all get the same UI.not handle the rendering logic by themself.
rabashani
Then use method 2 - an XML that would be translated to the proper format where you need to.
Andrei Rinea
I LOVE ASP.Net, and I still think you could use it for your purpose. You can render a control to html manually, outside of any page lifecycle (see http://blogs.x2line.com/al/articles/859.aspx).
Adam A
Sorry, to clarify, you should make your objects into Controls in ASP.Net and then you can use the above method to serialize them into HTML. This probably is too big a change though if your classes don't already inherit from System.Web.UI.Control
Adam A
A: 

Is there a reason you do not want to create a custom control .ascx file that takes domain entities object as an argument and then you can make the gui any way you want. This way you could dynamically add the controls to the page and just set a property to populate them.

Edit 1: Just render the control to an HTMLTextWriter instead of placing it on the page.

        StringBuilder outString = new StringBuilder();
        StringWriter outWriter = new StringWriter(outString);
        HtmlTextWriter htmlText = new HtmlTextWriter(outWriter);
        System.Web.UI.WebControls.Label lbl1 = new System.Web.UI.WebControls.Label();
        lbl1.Text = "This is just a test!";
        lbl1.ToolTip = "Really";
        lbl1.RenderControl(htmlText);
        ViewData["Output"] = outString.ToString();

Output

<span title="Really">This is just a test!</span>

Of course use your custom control instead of a built in control but this was a quick and easy demo.

benjamin
I am not working in a web team, I am rendering objects-as-html and send them to anyone else - who can use this in wpf\palm\web-site or other technology, so I guess ascx is not good for me
rabashani
But you can still render your control to an html text writer and pass that value. That way you can still design and maintain an ascx for convenience and simplicity over that of writing your own xsl or template engine.
benjamin
added code to my answer to show how ascx could work just fine.
benjamin
+1  A: 

I once had a need to render a collection of any type to an Html Table. I created an extension method on IEnumerable<T> that had overloads for css and the like. You can see my blog post about it here:

http://crazorsharp.blogspot.com/2009/03/cool-ienumberable-extension-method_25.html

It uses reflection to get all the properties of the object, and renders a nice little table. See if that would work for you.

BFree
A: 

Personally, I'd combine method two and three: Just create a generic XML document using reflection, say:

<object type="xxxx">
    <property name="ttt" value="vvv"/>
    ...
</object>

and use an XSTL stylesheet to create the actual HTML from this.

MartinStettner
+2  A: 

I can't agree more with John Feminella. Integrating Html rendering directly into your domain entities is a horrid pollution of your domain with a completely arbitrary and external concern. Like John said, you will make your entities very brittle by doing that, and break both of those critical rules: Separation of Concerns and Single Responsibility.

From the choices you gave, #3 is the closest to an appropriate way to do it. You need not write your own template engine. There are plenty free and ready-made template engines on the net that will do the job more than adequately (NVelocity, StringTemplate, Brail, etc. etc.)

Keep rendering where it belongs...in your presentation/view, and don't pollute your domain with higher level concerns.

jrista