老赵点滴


  先做人,再做技术人员,最后做程序员。
  我的理想:“让外国人看中国人写的技术书籍和文章”。Try as I might
posts - 290, comments - 10849, trackbacks - 158, articles - 6
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

方案改进:直接通过User Control生成HTML

Posted on 2008-07-14 13:24 Jeffrey Zhao 阅读(21992) 评论(73)  编辑 收藏 所属分类: ASP.NET

  对于使用User Control生成HTML的方式,大家应该已经比较熟悉了,老赵也曾经写过一篇文章(《技巧:使用User Control做HTML生成》)来描述这个做法。使用User Control进行HTML生成最大的好处就是将表现(Presentation)逻辑集中在一处,并且能够让前台开发人员使用传统的方式参与到页面开发中来。在其他方面,使用User Control生成HTML的做法直接使用了ASP.NET WebForms引擎,在开发时能够利用到ASP.NET的各种优秀实践。

  在“我的衣橱”中大量使用了这种生成HTML的做法。不过当项目达到一定规模之后,这个方法的不足之处也慢慢地体现了出来。就拿《技巧:使用User Control做HTML生成》作为例子来讲,除了显示上必要的Comments.aspx页面和Comments.ascx控件之外,还有一个额外的GetComments.ashx进行客户端与服务器端之间的通信。不过问题就出在这里,当此类做法越来越多时,项目中就会出现大量的此类ashx文件。冗余代码的增加降低了代码的可维护性,试想如果我们需要在某个控件上增加一个额外的属性,就需要去Handler那里编写对应的逻辑。虽不算是繁重的工作,但是如果能解决这个问题,无疑是一个锦上添花的做法。

  如果要避免大量Handler的出现,必然需要找到这些Handler的共同之处。这一点并不困难,因为每个Handler的逻辑的确大同小异:

  1. 使用ViewManager加载User Control
  2. 从QueryString或Form中获取参数,并设置对应属性
  3. 使用ViewManager生成HTML代码,并使用Response.Write输出

  写一个统一的Handler来将User Control转化为HTML是一件轻而易举的事情。不过因为有第2步,我们就必须应对为不同控件赋不同值的情况。这种“描述性”的内容即是该控件的“元数据(metadata)”,而说到“元数据”各位应该就能很快想到自定义属性(Custom Attribute)这个.NET特有的事物。因此我们的解决方案也使用这种方式来对控件的属性进行“描述”,且看该属性的定义:

public enum UserControlRenderingPropertySource
{
    Form,
    QueryString
}
 
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class UserControlRenderingPropertyAttribute : Attribute
{
    public string Key { get; set; }
 
    public UserControlRenderingPropertySource Source { get; set; }
}

  这个自定义属性只能标记在属性上,而它的作用是定义这个属性值的来源(是Query String还是Form)与集合中的键名。而我们的实现还会根据属性上标记的DefaultValueAttribute为属性设定默认值。定义了Custom Attrubte之后,我们就可以编写这个统一的Handler了。为了在客户端“隐藏”直接请求ascx文件的事实,我们只响应对扩展名为“ucr”的请求:

public class UserControlRenderingHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string appRelativePath = context.Request.AppRelativeCurrentExecutionFilePath;
        string controlPath = appRelativePath.ToLower().Replace(".ucr", ".ascx");

        var viewManager = new ViewManager<UserControl>();
        var control = viewManager.LoadViewControl(controlPath);
 
        SetPropertyValues(control, context);
       
        context.Response.ContentType = "text/html";
        context.Response.Write(viewManager.RenderView(control));
    }
}

  上面代码中的SetPropertyValues方法便是为User Control实例的属性赋值:

private static void SetPropertyValues(UserControl control, HttpContext context)
{
    var metadata = GetMetadata(control.GetType());
    foreach (var property in metadata.Keys)
    {
        object value = GetValue(metadata[property], context) ?? GetDefaultValue(property);
        if (value != null)
        {
            property.SetValue(control, Convert.ChangeType(value, property.PropertyType), null);
        }
    }
}

  SetPropertyValues方法中会调用三个方法:GetMetadata,GetValue和GetDefaultValue。GetMetadata方法会得到关于这个control的元数据,为PropertyInfo - List<UserControlRenderingPropertyAttribute>的键值对(即Dictionary)。然后将metadata传入GetValue方法,以获取由UserControlRenderingPropertyAttribute标记的值。如果GetValue方法返回null,则调用GetDefaultValue方法获取标记在该属性上DefaultValueAttribute。以下就将其余代码附上,没有技术含量,但做一参考:

[展开代码]

  至此,UserControlRenderingHandler完成了。不过在真正使用时,还需要进行一些配置。例如,您需要在IIS的ISAPI Mapping中将“.ucr”与aspnet_isapi.dll进行映射,并且在web.config中将*.ucr与UserControlRenderingHandler关联起来。当然,对User Control的属性进行标记是必须的。例如还是《技巧:使用User Control做HTML生成》一文中的例子:

public partial class Comments : System.Web.UI.UserControl
{
    protected override void OnPreRender(EventArgs e)
    {
        // ...
    }
 
    [UserControlRenderingProperty(Key = "page", Source = UserControlRenderingPropertySource.QueryString)]
    public int PageIndex { get; set; }
 
    [DefaultValue(10)]
    public int PageSize { get; set; }
 
    // ...
}

  然后,在客户端代码中只要根据路径发起请求即可,UserControlRenderingHandler会在服务器端完成余下的工作。

<script type="text/javascript" language="javascript">
    function getComments(pageIndex)
    {
        new Ajax.Updater(
            "comments",
            "/Controls/Comments.ucr?page=" + pageIndex + "&t=" + new Date(),
            { method: "get" });
       
        return false; // IE only
    }
</script>

  不过,这就够了吗?对于一个例子来说,这已经足够了,不过要在产品环境中使用很可能还略显不够。例如,如果只让用户访问到特定的User Control,或者只有特定权限的用户才能访问,又该如何对UserControlRenderingHandler进行改造呢?相信您了解上述做法之后,这点要求对您一定不成问题。

Feedback

#1楼    回复  引用  查看    

2008-07-13 20:46 by Indigo Dai      
沙发
先顶再看
老赵好久不发问啦

#2楼 [楼主]   回复  引用  查看    

2008-07-13 20:50 by Jeffrey Zhao      
点子不错,实现没啥技术含量——点子是Dflying提出的,老赵负责实现和改进。

#3楼 [楼主]   回复  引用  查看    

2008-07-13 20:50 by Jeffrey Zhao      
@Indigo Dai
忙……
懒……
主要是后者……

#4楼    回复  引用  查看    

2008-07-13 21:24 by 李涛      
抢个地板
代码我就先不看了,知道老赵喜欢耍内功了,呵呵

#5楼 [楼主]   回复  引用  查看    

2008-07-13 21:40 by Jeffrey Zhao      
@李涛
啥叫耍内功呀?

#6楼    回复  引用  查看    

2008-07-13 21:54 by 李涛      
@Jeffrey Zhao
川话中喜欢把玩,用等说成耍,老赵早已经练就北溟神功,故曰:耍内功啊

#7楼    回复  引用  查看    

2008-07-13 22:03 by 醉春风      
看了题目,顿觉自己最近想要的一个东西可以实现了。
这个做法我的好好看看。
thanks

#8楼    回复  引用  查看    

2008-07-13 22:33 by 王孟军!      
好东西,有时间研究研究

#9楼    回复  引用  查看    

2008-07-13 23:09 by 代码乱了      
关注中,明天再研究

#10楼    回复  引用  查看    

2008-07-13 23:44 by Tony Zhou      
网站美女挺多

#11楼    回复  引用  查看    

2008-07-14 01:16 by Clingingboy      
从HttpHandler去取UserControl的数据并不是一种很好的办法。
老赵把请求的参数以暴露控件的属性的方式,然后把参数传给控件.
由于UserControl是必须放在Page里面的,但现在是在HttpHandler中创建一个Page对象,实际中,这个创建出来的Page对象无法获取到请求的参数,这就导致了这个Page只能做为UserControl的一个容器的作用而已,其已经失去了很多功能。如果逻辑有些复杂的话,则需要定义更多的属性,由外界传值进去。
如果单单是应用于分页还好说。个人认为可以通过User Control产生数据,但不应该在HttpHandler里面为了得到User Control的内容而去创建一个Page对象。HttpHandler更适合于传输json和xaml之类的数据。我的做法是先创建一个page页面,由这个已经创建好的页面来负责加载这个User Control.并不会因为其是Page而在速度上比HttpHandler慢。因为User Control就是基于Page的,有了Page做的事情还是很多的

#12楼 [楼主]   回复  引用  查看    

2008-07-14 02:29 by Jeffrey Zhao      
@Clingingboy
哪些请求参数取不到啊?所有的参数都在HttpContext上,和Page有什么关系,现在是为了生成User Control的HTML,所有的逻辑都是在User Control上的,Page对象在这里本就是个Helper而已。如果有任何需要用到Page中逻辑的地方就是设计上的错误了。就像Page本不应该知道它属于哪个特定的master page,control本不应该知道它属于哪个page一样。
再者如果是请求一个页面而输出一个HTML片段的话,这就是个设计上的问题了(UpdatePanel这种为了特殊目的自然是个例外)。就像当年AJAX刚出现时很多人不知道有ashx这回事,就用个几乎为空的aspx来Response.Write数据一样,的确能用,但是不能不说是个问题。
而且HttpHandler本来就是随心所欲地输出各种数据流,何谈适合json/xaml的数据……我还能用它输出图片、输出各种文件呢。

#13楼    回复  引用  查看    

2008-07-14 04:53 by LuChaoShuai      
public void ProcessRequest(HttpContext context)
{
HttpApplication app = context.ApplicationInstance;
string appRelativePath = app.Request.AppRelativeCurrentExecutionFilePath;
string controlPath = appRelativePath.ToLower().Replace(".ucr", ".ascx");
var viewManager = new ViewManager<UserControl>();
var control = viewManager.LoadViewControl(controlPath);
SetPropertyValues(control, context);
app.Response.ContentType = "text/plain";
app.Response.Write(viewManager.RenderView(control));
app.Response.StatusCode = 200;
app.CompleteRequest();
}


Request.AppRelativeCurrentExecutionFilePath;
以前不知道还有这么一个属性.谢谢了.

#14楼    回复  引用    

2008-07-14 04:59 by Alvan [未注册用户]
“control本不应该知道它属于哪个页面”,这句话只说对了一半。它可以不知道它属于哪个页面,但是它一定要知道它不该属于哪个页面——以user control为载体加载异步HTML片段的一个潜在问题就是客户端id冲突,而且在规模稍大的项目中这几乎是一定会出现的问题,除非建立一套完整的server control命名方案或者保证客户端脚本决不使用客户端id。显然这两项要求都是一线程序员最讨厌的东西,所以如果一定要用uc来作为载体,我更倾向于用iframe加载HTML。

#15楼    回复  引用  查看    

2008-07-14 05:03 by 怪怪      
其实把这个和UpdatePanel的优点全都占了并统一化的方案也不是没有, 不过在框架上就需要一整套了, 等真能闲下来, 我也拿出来晒晒。 可惜就是我写不出像你这么好的技术文章, 最后估计又是乱七八糟。

@Alvan
你说的这些, 花点功夫还是能解决的 :)。 还可以实现过在客户端和服务器端统一的FindControl这样的功能: 只要咱们自己在两边都维护了控件树信息。

#16楼    回复  引用  查看    

2008-07-14 08:41 by micenter      
顶一个

#17楼    回复  引用  查看    

2008-07-14 09:03 by Clingingboy      
Page与控件的关系是。Page可以没有控件,但控件不能没有Page.控件可以不知道其放在哪个Page,但应该可以知道Context。
ashx和aspx最终同为url请求,不同的则是aspx需要在项目中建立一个实体的文件而已,给人的感觉就是模块多了,代码就淤泥了,紧紧为了ajax的数据传输而建页面.当然aspx也能产生数据流,很多人用aspx作为一个页面做验证码,技术上可行,但用HttpHandler更合理.
我的做法是依赖于一个Page,在其基础上进行封装.犹如ajaxpro这种做法.
再者如果UserControl职责单一只用于分页,功能确定下来,就可以封装成自定义控件了,建多个UserControl也并不是很好,这个UserControl最后需要封装就是输出HTML的一个模板.

当然这里只讨论后端生成数据,与前端如何去取后端数据无关,两者可以结合也可以分开.

关于控件ID的问题,可以通过控件适配器来解决。当然这是要有一定牺牲的.如果控件仅仅(即失去了webform的一些功能)显示而已的话是可以这么做.

还有如果这个UserControl脱离了这种在HttpHandler下生成HTML的模式.似乎就意义不大了.
个人见解:)

#18楼    回复  引用  查看    

2008-07-14 09:24 by 坏人      
文章还没细读,怀疑需求的存在必要性。

#19楼    回复  引用  查看    

2008-07-14 09:29 by willieQ      
正需要,收下,回去仔细看~~~~

#20楼 [楼主]   回复  引用  查看    

2008-07-14 09:35 by Jeffrey Zhao      
@Clingingboy
在Handler中使用User Control生成HTML意义很大,UserControl在这里就是个独立的模板,而且这种情况下如果要用来生成HTML的User Control,其逻辑一定是内聚的,否则就是设计上的失误。
说到AJAX Pro,我觉得他一大败笔就是把好好的AJAX Method与页面绑定在一起,但是却没有任何必要,也没有带来任何益处。所以ASP.NET AJAX选择了外部Web Service这样的做法,灵活多了。
其实你就这样想,平时请求的是aspx,现在请求的是ascx而已,目标就在aspx和ascx上,没有其他的。

#21楼 [楼主]   回复  引用  查看    

2008-07-14 09:35 by Jeffrey Zhao      
@坏人
放心,这个做法是经过实际项目考验的,从可用性到必要性都没有问题。

#22楼    回复  引用    

2008-07-14 10:47 by 东 [未注册用户]
酷哦....

#23楼    回复  引用    

2008-07-14 10:57 by 子曰2 [未注册用户]
为什么一定要用User Control ,用Page 不行吗。第一次也用异步请求生成Html

#24楼    回复  引用  查看    

2008-07-14 10:59 by Clingingboy      
关于绑定的Method是分类型的,如数据相关的操作可以不放在页面里面,确实绑定起来没必要,抛开这个来讲,其实在Handler同样是需要与方法绑定起来的,这实际上是一个一样的逻辑.同样也可以通过注册的方式在页面上注册Service分离页面与Service.
我确实是这么想的,通过aspx请求,原因是Handler无法满足我的需求。

如果通过传值的话,这个UsrControl功能变的很单调.

#25楼    回复  引用    

2008-07-14 11:01 by opend@live.cn [未注册用户]
通过User Control生成Html,然后通过IHander得到相关Html,然后通过Ajax调用控制。。。为什么不直接使用IHander输出Json数据?效率应该更高。UserControl可能共用。。。JS也可以。。。
不过思路很不错

#26楼    回复  引用  查看    

2008-07-14 11:05 by rockshit      
功能、设计、以及技术实现方面的问题貌似改分开讨论。

#27楼    回复  引用  查看    

2008-07-14 11:09 by rockshit      
ajaxpro的优势的明显的,简单,单纯。ajax.net的使用外部web service的是灵活但是开发有一定的冗余。不可否认的是ajax.net模式在一定程度上也相当简单,但是效率牺牲是一定的。

#28楼 [楼主]   回复  引用  查看    

2008-07-14 11:10 by Jeffrey Zhao      
@Clingingboy
举个Handler不能满足需求的例子吧

#29楼 [楼主]   回复  引用  查看    

2008-07-14 11:11 by Jeffrey Zhao      
@rockshit
ajax.net就是ajaxpro。应该说是asp.net ajax。
你说效率上牺牲什么了?
ajaxpro和asp.net ajax实现机制差不多,效率没有差别。

#30楼    回复  引用    

2008-07-14 11:42 by matta [未注册用户]
好笑.让我想起一个 通过请求自己的页生成html的方法.

#31楼 [楼主]   回复  引用  查看    

2008-07-14 11:58 by Jeffrey Zhao      
@matta
你似乎没有看懂我的做法?

#32楼    回复  引用    

2008-07-14 12:03 by 子曰2 [未注册用户]
有个问题,如果 UserContorl 被 UserControlRenderingHandler 处理了。那么
.ascx的还会不会被HttpForbiddenHandler 处理。如果HttpForbiddenHandler 再处理,启不是加载了2次UserContorl

#33楼    回复  引用    

2008-07-14 12:11 by 子曰2 [未注册用户]
.ascx 默认的 处理是由HttpForbiddenHandler来处理的。
<add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>

#34楼 [楼主]   回复  引用  查看    

2008-07-14 12:13 by Jeffrey Zhao      
@子曰2
你看我的代码,请求的不是.ascx而是.ucr

#35楼 [楼主]   回复  引用  查看    

2008-07-14 12:14 by Jeffrey Zhao      
@子曰2
一个扩展名不能被两个handler或handlerfactory处理。

#36楼    回复  引用    

2008-07-14 12:14 by 子曰2 [未注册用户]
哦。看到了 。其实也没必要。刚查询到MSDN的一句话了。
在WEBconfig 设置 httphandle 时 。要注意的是相同的后缀名配置多次的话,后面的配置会把前面的覆盖。

#37楼    回复  引用    

2008-07-14 12:15 by 子曰2 [未注册用户]
恩。呵呵。刚刚自己问了个很BC的问题。不好意思!

#38楼 [楼主]   回复  引用  查看    

2008-07-14 12:15 by Jeffrey Zhao      
@子曰2
其实我文章里也写了……是为了“不要太过暴露”……

#39楼 [楼主]   回复  引用  查看    

2008-07-14 12:16 by Jeffrey Zhao      
--引用--------------------------------------------------
子曰2: 恩。呵呵。刚刚自己问了个很BC的问题。不好意思!
--------------------------------------------------------
客气

#40楼    回复  引用    

2008-07-14 12:16 by 子曰2 [未注册用户]
恩,学习!

#41楼    回复  引用    

2008-07-14 12:43 by 子曰2 [未注册用户]
UserControlDirectAccessPropertySource 这个类好像没看到定义的。
是不是写错了。应该是 这个 UserControlRenderingPropertySource枚举类型

#42楼 [楼主]   回复  引用  查看    

2008-07-14 13:21 by Jeffrey Zhao      
@子曰2
没错,谢谢指正。

#43楼    回复  引用  查看    

2008-07-14 15:15 by SZW      
把Form和QueryString区分开来主要用意是什么呢?

#44楼 [楼主]   回复  引用  查看    

2008-07-14 16:56 by Jeffrey Zhao      
@SZW
没啥用意,就是分开了。
既然标记了就详细一些,比如Form的key1里获取或者QueryString的Key2里获取属性值。

#45楼    回复  引用  查看    

2008-07-14 17:27 by 果果’er      
我也是看了这个以后,自己写了个page来按参数载入UserControl,(?uc=ucABC)
其它的参数则让UserControl自己去获取。

感觉这样用UserControl的好处是页面上可以首次有输出,又还可以简单做Ajax。
我甚至把Ajax都写到UserControl自己里面了,可以自己重新载入自己 :)

#46楼    回复  引用  查看    

2008-07-14 19:10 by 随风流月      
@Jeffrey Zhao
Ajax Pro 的 Method 不一定要和 Web Page 绑定的...

#47楼    回复  引用  查看    

2008-07-14 19:28 by airwolf2026      
就像当年AJAX刚出现时很多人不知道有ashx这回事,就用个几乎为空的aspx来Response.Write数据一样,的确能用
-------------------------------------
-_-!!!俺前几天还这样写....还说page为啥把屁股也给输出出去了...哈哈...

#48楼 [楼主]   回复  引用  查看    

2008-07-14 20:24 by Jeffrey Zhao      
@果果’er
我这里UserControl不太自己取,因为页面上也会复用这个控件。

#49楼 [楼主]   回复  引用  查看    

2008-07-14 20:24 by Jeffrey Zhao      
@随风流月
这还差不多

#50楼 [楼主]   回复  引用  查看    

2008-07-14 20:24 by Jeffrey Zhao      
@airwolf2026
屁股?

#51楼    回复  引用    

2008-07-16 21:43 by hotjava [未注册用户]
还是用的您上次发的那种老办法,可是我如果使用的是gridview而不是repeater, 就会出现
Error executing child request for handler 'System.Web.UI.Page'

请问这是什么原因呢。? 多谢

#52楼    回复  引用  查看    

2008-07-21 18:17 by Cat Chen      
如果用RoR的思维来做,应该连ucr => ascx的替换也不用,就让用户请求ascx。因为Ajax.Updater会加上一个header声明这是Ajax请求,你拦截请求然后根据header判断怎么处理就够了,更加简洁。

#53楼    回复  引用    

2008-07-21 20:36 by win [未注册用户]
有个DEMO看过来可能更好
这样看着那些代码有点烦
不过老赵还是很利害地
顶一下

#54楼 [楼主]   回复  引用  查看    

2008-07-21 21:44 by Jeffrey Zhao      
@win
要的就是这个效果,希望读者能够好好阅读代码

#55楼 [楼主]   回复  引用  查看    

2008-07-21 21:46 by Jeffrey Zhao      
@Cat Chen
我就是不希望加特别的header,呵呵。
而且最终还是要写一个Handler(甚至为了看Header还需要一个Module)……

#56楼    回复  引用    

2008-07-24 11:45 by lixyvip [未注册用户]
看了一下 我的衣橱 网站,感觉不错

#57楼    回复  引用  查看    

2008-07-28 11:14 by 凌风      
我倒觉得老赵的做法很合理呀。
支持,同时也希望各位在沟通时先把文章看完。

#58楼    回复  引用  查看    

2008-08-06 09:09 by 假正经哥哥      
@Jeffrey Zhao
UserControl 在做通用的Ajax 效果时候还是很有用的。比如把这里的UserControl 变成Webpart ,那么我们可以定义通用的Webpart基类,抛出回调的JS获取Webpart实际的HTML,可以实现通用的带有ajax功能的Webpart,在实际编码人员开发webpart的时候就不需要考虑ajax的效果,只要去实现webpart本身的逻辑就可以了

#59楼    回复  引用  查看    

2008-08-14 19:53 by Evernory      
太猛了~学习了~

#60楼    回复  引用  查看    

2008-08-17 17:20 by Indigo Dai      
看了文章,第一感觉就是老赵的基本功很强很强,Attribute那段代码博客圆子里能写出的应该为数不多吧。过硬的基本功,再加上其他知识,这才叫程序员啊……

#61楼    回复  引用  查看    

2008-09-01 16:32 by 胡一刀      
如果不用这种 获取Custom Attribute的 方法,反射是不是也可以呢?
看3.5的语法,似乎有点不习惯

#62楼 [楼主]   回复  引用  查看    

2008-09-01 20:18 by Jeffrey Zhao      
@胡一刀
Custom Attribute不就是反射吗?

#63楼    回复  引用    

2008-09-25 05:19 by vilyliao [未注册用户]
一个字:强!
几个字:老赵太强了!
-------------------------
有点疑问:
1、老赵你不是ajax深入浅出的讲师吗?干么不用asp.net ajax框架做啊?
把Usercontrol直接放在一个UpdatePanel中不就得了?
(是不是您只是为了讲解这个技巧才这样做呢?)
2、个人感觉这样做的性能(包括使用UpdatePanel)这样做都不是最佳的,
不如在提交Comments时使用ajax方式提交保存到数据库,客户端直接使用js,AppendChild一个回复就可以了,您以为如何?
(严重佩服您的勤劳与勇敢,我的第2点想法也没有实践,但一定行得通,本人
太懒了,就不去实践啦!)

#64楼    回复  引用  查看    

2008-09-26 21:12 by SuperSaiyan      
我的几点改进意见,
http://www.cnblogs.com/kakrat/archive/2008/09/26/1299824.html

#65楼 [楼主]   回复  引用  查看    

2008-09-27 10:13 by Jeffrey Zhao      
@vilyliao
1、我也不是到处用asp.net ajax阿,ajax其实从来就是我的副业……
2、我的做法有其好处,方便,而且容易维护。

#66楼 [楼主]   回复  引用  查看    

2008-09-27 10:15 by Jeffrey Zhao      
@SuperSaiyan
我现在是能让一个最普通的User Control得到支持,而不是为这个功能进行特殊处理。当然您的做法也可以,我们出发点有点不一样。
至于所谓反射所带来的性能问题,它远不会是性能瓶颈,而且您要知道,您用的asp.net里的各种功能相当部分是基于反射的——其他框架也是。

#67楼    回复  引用  查看    

2008-09-27 11:00 by SuperSaiyan      
对user control 的 override oninit, 是一个很自然和常见的事情, 把获得参数的逻辑放在其中, 不算特殊处理, 并且符合封装原则. 而你的办法, 用attribute和一段通用的逻辑处理来解决同样的事情, 有点overkill, 感觉不自然. 让user control implment interface, 可能也是有点overkill, 但是, 起码不会用到很多反射, 也符合封装原则.

动态的user control 的oninit, 会在它被加入parent的children时, 被系统调用.

反射对于desktop application, 一般来说关系不大. 但是, 对于web server来说, 是要尽量避免的. 我的方案里, 反射的使用降到了最底, 可能在最初获得配置参数部分, .net内部会用到一点反射, 但不是对每个请求都需要使用很多的反射.

#68楼    回复  引用    

2008-09-30 11:12 by www.dache.cn [未注册用户]
老赵,分页呢,你这么做了,分页如何解决阿!? 如果分页没解决这个方法是不是基本上没什么实际意义呢!

#69楼 [楼主]   回复  引用  查看