在 ASP.Net 中将数据对象转换为 HTML 的简单机制

发布于 2024-08-15 19:10:55 字数 1561 浏览 3 评论 0原文

我正在寻找一种将数据对象转换为 HTML 的机制。数据对象中的元素有简单类型和复杂类型。我尝试过使用 HtmlTextWriter 进行渲染,但陷入了复杂类型的困境。

我的是一个 ASP.Net 网站项目。我必须避免使用服务器端控件(因此放弃内置的绑定功能),因为前端处理是在 jQuery 的帮助下完成的。我只需要为我的数据对象制作基本的 HTML,其余的丰富(内容安排和样式)将在前端完成。

我正在寻找一个简单的解决方案(我发现 Spring.Net 过于杀伤力和压倒性的,并且 NHAML 也非常令人困惑)。

此外,我的应用程序预计会在一段时间内增长,因此我需要对性能有一定的尊重。因此,我避免将 XML/XSLT 纳入考虑范围。


例如。 Person 对象将类似于:

String: Name
智力:年龄
复杂类型:地址(包括街道、城市、邮政编码)
类型数组 “资格”:资格(包括学位、通过年份、成绩)

期望的输出是:

<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>

这里需要注意的一点是,映射器需要映射从源数据对象获取属性,向其中添加一些元数据(如 HTML 元素属性等),然后执行转换。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不爱素颜 2024-08-22 19:10:55

我将其视为一个设计问题,并从更高的角度来详细回答,即设计而不是代码!正确的方法如下。

  • 人员类型持有信息,并且以数据为中心,因此我建议不要将任何 html 渲染责任放入此类中.

  • 首先,您需要为所有业务/数据对象提供一个抽象基类。让我们假设[因为您需要拥有它]BusinessBase

  • 因此,您应该开始编写一个派生自 System.Web.UI.WebContorl 的服务器控件。公开一个在其设置访问器中采用 BusinessBase 类型对象的属性。

  • 现在您需要定义一些自定义属性,这些属性应用于 BusinessBase 类型的任何子类的属性。该属性保存业务/数据对象的特定属性的渲染输出信息。 装饰您想要在 html 中呈现的所有属性

  • 返回到您的 Web 服务器控件,并通过使用反射来迭代已分配给 BusinessBase 类型的服务器控件属性的对象的所有属性 [具有您的自定义属性]根据属性渲染 html

现在,在您的 ASP.NET 前端中使用此 Web 服务器控件和业务对象。玩得开心。

这是一个高级设计。你需要更加谨慎和
具体说明您的属性
html 渲染是为
业务对象。

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.

千紇 2024-08-22 19:10:55

您是否对 XmlSerializer 或 DataContractSerializer(更快)与 xslt 转换一起进行了基准测试,因为您立即放弃了它们?

如果您仍然认为 xslt 对于您的服务器来说太慢,请让客户端将其呈现为 xhtml。然后CPU“负担”就被分配给你的所有用户了。

可以在 w3schools.com 上找到教程。

考虑未来的扩展是明智的,但在你真正知道它会成为瓶颈之前,你不应该忽视一个明显的技术和解决方案。

与采用更复杂的编程路线相比,您还应该计算添加另一个前端服务器的成本。您还可以研究缓存以提高性能。

[编辑]
另一个解决方案是为每个类实现一个 WriteHtml 方法,并从顶级类中调用所有子编写器。手动且有效(但需要更多管理,因为如果添加属性,则必须更新编写器)。

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>" );
   }
}

您还可以重写每个类中的 ToString() 以返回 html 表示形式,并使用它。

既然您声明类很简单,那么它应该是可维护和可读的,但我仍然喜欢 xslt,因为它更容易更改而无需重新编译。最复杂的渲染部分是渲染容器标签,因为您保留了对象数组。如果您为它们实现了 Collection 类,那么您可以在该类中维护 Container 标记。

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

那么问题是,你认为什么是“简单”:D

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文