views:

64

answers:

2

Hello. I am looking for a mechanism to transform dataobjects into HTML. The elements in the dataobject are of both, simple and complex types. I have tried playing with HtmlTextWriter for rendering but got stuck with complex types.

Mine is an ASP.Net website project. I have to avoid using server side controls (and therefore do away with built in binding capabilities) as the front end processing is done with the help of jQuery. I need to just churn out basic HTML for my dataobjects and the rest of enrichment (content arrangement and styling) will be done at the frontend.

I am looking for a simple solution (I found Spring.Net an overkill and overwhelming and NHAML also very confusing).

Further, my application is expected to grow over a period of time so I need to have some respect for performance. Therefore I am avoiding bringing XML/XSLT in the picture.


For eg. A Person object will be something like this:

String: Name
Int: Age
Complex Type: Address (includes Street, City, Zip)
Array of Type "Qualification" : Qualifications (includes Degree, Passing Year, Grades)

Desired output is:

<p id="userName" class="userName">John</p>
<p id="age" class="age">35</p>
<div id="address" class="address">
    <p id="street" class="street">Express Highway</p>
    <p id="city" class="city">Mumbai</p>
    <p id="zip" class="zip">400101</p>
</div>
<div id="qualifications" class="qualifications">
    <div id="qualification1" class="qualification">
        <p id="degree1" class="degree">B.Sc.</p>
        <p id="year1" class="year">1990</p>
        <p id="grade1" class="grade">A</p>
    </div>
    <div id="qualification2" class="qualification">
        <p id="degree2" class="degree">M.Sc.</p>
        <p id="year2" class="year">1992</p>
        <p id="grade2" class="grade">A</p>
    </div>
</div>

A point to note here is that a mapper would be required to map the properties from the source dataobject, add some metadata to it (like HTML element attributes, etc) and then carry out the transformation.

A: 

Have you benchmarked XmlSerializer or DataContractSerializer (faster) together with xslt transformations, since you're dismissing them off the bat?

If you still consider xslt to be too slow for your server, let the client render it as xhtml. Then the cpu "burden" is distributed to all your users.

A tutorial can be found at w3schools.com.

It's wise to think about scaling for the future, but you shouldn't dismiss an obvious technology and solution before you actually know it will be the bottleneck.

You should also calculate the cost of adding another front-end server compared to going a more complicated programmatic route. You can also look into caching to improve performance.

[Edit] Another solution is to implement a WriteHtml method for each class, and from your top class you will call all your child writers. Hand-rolled and effective (but takes more management since you must update the writer if you add a property).

class Person
{
   public void WriteHtml(Stream writeStream);
   {
     writeStream.Write( "<p id="userName" class="userName">{0}</p>", UserName );
     etc.
     Adress.WriteHtml(writeStream);
     writeStream.Write( "<div id="address" class="address">" );
     foreach( Address ad in Adresses ) ad.WriteHtml(writeStream);
     writeStream.Write( "</div>" );
   }
}

You could also override ToString() in each class to return the html representation, and use that instead.

Since you state that classes are simple it should be maintainble and readable, but I still favor xslt, as it's easier to change without recompile. And the most complex render part you ahve is to render your Container tags, since you keep Arrays of objects. If you implemented a Collection class for them, then you could maintain the Container tags in that class instead.

class Person
{
   AddressCollection Adresses;
   // instead of
   Adress[] Adresses;
}

Then the question is, what do you consider "simple" :D

Mikael Svenson
Mikael, thanks for the perspective. Actually I am looking for opinions from the forum for a more convenient, more manageable and simpler approach. XML is not completely out, I've just parked the idea for the time being. Just like there are many professional quality tools available for object-data modeling, I've been wondering why there aren't any for service-presentation. Of course the latter situation is bit more complex comparatively but certainly there are many known patterns to play with. I just want to check with the community first before I choose from the ones I know.
Kabeer
Added another option as well.
Mikael Svenson
Thanks Mikael for clarity.
Kabeer
A: 

I'm looking at it as a design problem and elaborate answer on much higher perspective that is design and not the code! The correct way to do this would be as following.

  • Person type is holding the information and it is data-centric so I recommend not to put any html-rendering responsibility into this class.

  • First you will need to have an abstract base-class for all your business/data objects. Let us assume [becuase you'll need to have it] BusinessBase.

  • So you should start writing a server-control that derives from System.Web.UI.WebContorl. Expose a property that takes an object of type BusinessBase in it's set accessor.

  • Now you need define some custom Attributes that is applied to properties of any sub-class of type BusinessBase. This attribute holds the renderring output information for that particular property of the business/data object. Decorate all properties which you want to be renderred in html.

  • Come back to your web-server-control and via use reflection to iterate through all properties [having your custom-attribute] of object which has been assigned to the server control property of type BusinessBase. Render the html as per the attribute.

Now use this web-server-control and business object in your asp.net front-ends. Have fun.

This is a high-level design. You'll need to be more discrete and specific in your attribute as to what html rendering is generated for the business object.

this. __curious_geek
Hey, thanks. Yes, certainly this is a design challenge and one that you've illustrated is good.
Kabeer