老赵点滴


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

  没想到我的文章引起了那么大的反应,看来最近MVC框架的确是一个热门话题。正如上一篇文章开始所说的,我不会对MVC框架有任何“贬低”,任何技术滥用都有问题,所以任何东西都会有所谓的Best Practice(去MSDN的Patterns & Practice栏目看看就知道了)。我写这几篇文章,是想说明,很多WebForms的缺点是被夸大了。WebForms的确有缺点,但是我们完全可以避开,并且仅仅利用到WebForms给我们带来的便利。这其实也是一种Best Practice。相信以后MVC框架也一定会出现这样的东西。

  在上一篇的评论中,有朋友说我是“边缘”的ASP.NET程序员,大概是因为我用WebForms但是抛弃ViewState、PostBack和GridView这种“重要”的东西吧。我不知道这样是不是“边缘”,但是我的确抛弃了不少东西。例如还有ADO.NET中的DataSet/DataTable——但是我们还有DataReader呢!抛弃了微软提供的一部分东西,我们其实可以发现,.NET里的基础组件一个都不少,用起来也会得心应手。

  去其糟粕,取其精华。

三、生成丑陋的HTML,难以进行样式控制

  在ASP.NET的WebForms刚出现时,各种“演示”看上去真的很美。这个特点微软至今还保留着,各微软技术大会上的演示真的让人感到心潮澎湃。在我看来,那些“激素大会”更是一种推广策略,而并没有将目光集中在技术细节的本身。所以微软的东西似乎总是有入门容易提高难的“毛病”。开发人员被“宠坏”了,上一篇文章中有位朋友说这就是“穷人的孩子早当家”,还是有一定道理的。在.NET环境下我们就像是官宦子弟,不过这并不能成为我们习惯于“吃喝嫖赌”的理由。我们要合理利用富裕的环境带给我们的资源,但是要适当地抛弃一些不好的东西。

  好像说了几句废话,现在进入正题。说到WebForms则不得不提丰富的控件,基于ASP.NET平台的第三方控件提供商似乎比其他平台下的总合还要多,这也是产业阿。在微软提供的控件里,GridView(或者1.1里的DataGrid)是被“演示”次数最多的,也似乎是最强大(还是差不多等同于“复杂”)的。有了GridView之后,很多开发人员就习惯于朝页面上拖个控件,然后再设计器里点点鼠标,设设样式,最后绑定一个DataTable上去。哗,好一个表格就此诞生。然后我们还可以响应其事件,对某一行数据进行编辑,删除。太轻松了,这世界一下子变得美好了起来。不过由于GridView过于“强大”,它几乎成为了ASP.NET初学人员的必修课,当对于Web开发都不明就里的初学者都习惯于GridView、GridView、GridView时,它的滥用也就不可避免了。于是乎,做表格,用GirdView,做列表,也用GirdView(不就是个只有一列的表格嘛)。

  可惜的是,GridView有很多毛病。如果要使用GridView的高级功能(添加、修改、删除等等),ViewState必不可少,再加上很多开发人员在绑定数据时没有经过筛选,导致ViewState变得无比庞大(例如显示一个文章列表,明明只需要ID、标题,创建时间等基本信息,却用一个“令人无比愉悦”的SELECT * FROM Article语句把文章内容也选择了出来并绑定在GridView上,ViewState中也就不得不包含几千几万字的多余数据)。

  不过现在想说的,倒是它生成出的HTML。

  GridView在客户端生成的HTML是个<table />,可惜这个<table />里东西太多了,的确显得很丑陋。不过更关键的在于,这个表格的样式实在难以控制。虽说GridView里从标题到单元格到低部都能够进行样式的定义,但是灵活度还是远远不够。再加上GridView生成的HTML死板而不符合Web标准(例如不会生成<th />标签,用ControlAdaptor进行改造的做法不算),但是优秀的样式开发人员大都是坚定的Web标准支持或推广者,ASP.NET对于标准支持不佳,难以控制样式的说法满天飞扬。

  我想为WebForms喊冤。不过首先我会打倒以GridView为首的复杂控件(包扩DataList、FormView等等)并狠狠踩上几脚。有人说,当抛弃了GridView之后,用WebForms还有什么意义?其实类似的话也不断在我说要抛弃ViewState和(复杂)的PostBack时出现。如果您觉得抛弃了这些东西WebForms就失去意义的话,那么我想说,ViewState、PostBack、GridView远不是WebForms的全部。我认为,Control模型(或者说组件化模型)才是WebForms的关键。而这个模型的“基础”是绝对优秀的。下面我会进行一些展示,虽然这些展示我觉得是基础中的基础。

  首先我们先来看一下最常用的用户控件的表现吧(DemoControl.ascx):

<%@ Control Language="C#" AutoEventWireup="true" %>

<%= "Hello World!" %>

  然后将它放在页面里:

<div>
    <uc1:DemoControl ID="DemoControl1" runat="server" />
</
div>

  在浏览器里打开页面会发现如下的代码:

<div>
    Hello World!
</
div>

  多干净的代码,我甚至连多余的空格都没有去除。还有一个例子就是Master Page,<asp:ContentPlaceHolder />也不会产生任何多余的代码。这说明了使用用户控件搭出的WebForms页面,是不会出现多余的“脏”代码的。如果您在观察那些基础控件,TextBox,CheckBox(不设Text属性),Panel等等,亦或是加上runat=server的HTML元素,无一例外(当然客户端ID的确还是比较长,关于这个问题我会在以后的文章进行讨论)。

  那么肮脏的Tag是哪里来的呢?当然是以GridView为首的复杂控件。那么如果我们要生成批量数据,又该怎么办呢?现在来看看Repeater的表现吧,就以最常见的无序列表为例:

<asp:Repeater runat="server" ID="rptItems">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li>
            <img src="<%# Eval("ImagePath")) %>" alt="<%# Eval("Title") %>" />
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>

  还是在浏览器里察看HTML(我这里就不贴出来了),一行多余的代码也没有。

  Repeater是ASP.NET 2.0中我最喜欢用的控件,它的功能很简单,把ItemTemplate和AlternatingItemTemplate的内容返回生成在页面上,并且将HeaderTemplate和FooterTemplate的内容显示在头尾。除此之外——没了。但是这已经足够了,对于绑定控件来说,还需要什么呢?这里面每一行代码都由我们自己编写,想定义样式也易如反掌,我们对于HTML的控制没有任何损失。

  另外,有些开发人员总认为ASP.NET中的DataTable绑定的方式让我们无法写出建模良好的代码。就算使用ObjectDataSource,在控制上也会有诸多不便。但这个也是一种误解,我们完全可以将领域模型中的对象绑定到视图里的控件上。首先是ASPX的内容:

<asp:Repeater runat="server" ID="rptItems">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li>
            <img src="<%# this.GetImagePath(Container.DataItem) %>"
                alt="<%# Eval("Title") %>" />

        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>

  然后是Code Behind:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        this.rptArticles.DataSource = this.GetArticles();
        this.rptArticles.DataBind();
    }

    protected string GetImageUrl(object dataItem)
    {
        return "http://img.jeffz.net/" + (dataItem as Article).ImagePath;
    }
}

  GetArticles方法的返回值可以是List<Article>或任何一个实现了IEnumerable<Article>接口的类型,这个样在ItemTemplate中访问Container.DataItem就会得到这个Article对象。我们在Code Behind类里定义一个protected方法,由于aspx最终会被编译为Code Behind类的子类,因此我们就可以在ASPX页面中调用GetImageUrl方法。在方法内部我们可以将object类型的DataItem转换成Article类型的对象,然后就可以做任意的处理了。

  非常方便,非常灵活,还有什么可挑剔的呢?。

  有。比如我们想要使用每行10个元素,最后一行如果不足就让右边空着的方式来展示,Repeater可能就难以实现了(其实不能这么说,按标准应该还是使用无序列表,用样式来进行控制,Repeater完全够用)。ASP.NET 1.1和2.0可能我们会使用DataList控件,只要把RepeaterColumns属性设为10即可。可惜DataList生成的元素要么是<table />,要么是<span />和<br />,让人头疼。但是在ASP.NET 3.5中又多了一个ListView控件,使用这个控件进行展示可以分组循环,可以指定容器,真可谓无比强大。重要的是ListView和Repeater一样,所有的HTML都由自己控制,一个多余的字符都没有。

  有了Repeater和ListView,真可谓打遍天下无敌手,任何页面的展示方式都不在话下。

  我们再走个极端吧,我们来看下面的呈现方式:

<ul> <% foreach (Article article in this.GetArticles())
   { %>
        <li>
            <img src="<%= "http://img.jeffz.net/" + article.ImagePath %>"
                alt="<%= article.Title %>" />
        </li>
<% } %>
</ul>

  上面的例子在ASPX页面中使用了内联的foreach语句进行显示。这样生成代码无论从干净还是自定义角度来说,都可以的让任何开发方式“无地自容”。但关键是,这个方式……为什么……恩,没错,说的难听,这是原始的ASP的开发方式;说的好听,这是“先进”ASP.NET MVC框架中模板的写法。这是不是很讽刺?但是这个的确是事实。Rick Strahl大牛也在他的Blog中写到:“我还记得在早些时候,那些ASP.NET的疯狂追随者们是多么不屑使用内联的脚本标签,或者使用显式的URL而不是PostBack来进行开发的做法,而其中的一些人现在又毫不犹豫地张开双臂去迎接MVC框架,这难道不讽刺吗?”而且由于ASP.NET MVC的特性(从Controller传递到View的只是一个ViewData对象),因此真正ASP.NET MVC的“模板”的写法还要多一次Cast,也就是类似于如下的写法(当然ASP.NET MVC可以使用强类型的ViewData,这样就免去了这样强行的Cast):

<ul> <% foreach (Article article in (ViewData["Articles"] as List<Article>))
   { %>
        <li>
            <img src="<%= "http://img.jeffz.net/" + article.ImagePath %>"
                alt="<%= article.Title %>" />
        </li>
<% } %>
</ul>

  这里就要谈到ASP.NET MVC了。其实光从View上来看,我不知道这算不算是进步(当然其实我不介意内联的写法,有时候反而更清晰)。ASP.NET MVC如果光从View(模板)方式来看,有点回到了当年的ASP方式(当然,还是补充了一些Helper)。ASP.NET MVC的特点在于M-V-C的分离,在于业务逻辑的触发方式,在于URL Routing的驱动方式,而不是模板化的写法。如果要说MVC在View层面比ASP.NET清晰,我是肯定不会同意的,因为我完全可以在WebForms的ASPX页面中“写成”ASP.NET MVC类似的方式。不知道您是否同意,至少我认为,使用WebForms内Repeater或ListView的写法,不会输给ASP.NET MVC的模板。而且事实上,在ASP.NET MVC中作为View使用的aspx页面里,我们完全也可以放置Repeater,然后再Page_Load方法里写代码,这更证明了,在View方面WebForms和ASP.NET MVC其实是非常相似的。

  刚才说了,ASP.NET MVC的重要特点,在于M-V-C之间的分离,非常清晰,而且Model和Controller之间能够进行独立的测试。但是WebForms也可以做到这一点,我在后面的文章中还会谈一下WebForms里如何使用MVC来做到清晰、分离和单元测试等等。而且,我似乎觉得某些WebForms中能够做到的东西在MVC框架里却无法或者很难实现。可能是我对于MVC的了解程度还不够多的缘故吧,等我先研究了MVC框架之后再说。:)

  讲到这里,您心中是否有了答案,WebForms究竟能否写出清晰美观的HTML?在WebForms控制样式是否困难?抛弃GridView,我们并没有什么损失,因为现在的网页中又有多少会用到GridView的功能呢?

  目前老赵在公司使用WebForms开发时会与一个专职的前台开发人员配合。他是我认识的最好的前台开发人员,编程能力强,经验丰富,对于各种浏览器中脚本和样式的差异和问题可谓了如指掌,只是在这之前他只用过PHP,并没有接触过ASP.NET WebForms。但是仅仅向他解释了几个控件生成HTML的方式,或者如何从服务器端获得ClientID之后,我们之间的配合就非常轻松顺畅了。无论是开发人员先写放控件然后由他进行修饰,还是他先写静态样式页面我们再进行替换,都工作的非常顺利。我现在已经能够专注于业务的实现,架构的设计,而彻底从页面样式的“泥潭”中解放了出来,最多编写一下简单的JavaScript代码。分工的明确,也使得我们的工作效率得到了相当的提高。

  所以最后我给大家的建议就是,尽可能地使用“纯粹”的服务器端控件。例如使用Repeater和ListView,其实写出优秀的页面非常容易。当然,即使这么做,还是会有一些缺点的,例如:

  1. 例如Repeater的ItemCommand事件已经无法使用了,因为它会用到ViewState。但是我们开发的大部分的页面甚至连PostBack都不需要,这又有什么关系呢?
  2. 使用服务器端控件虽然能让我们对于HTML有十足的控制,但是我们无法避免在客户端生成一个不规则的ID。这一点理论上可能会影响页面样式的开发,但是就我那前台开发人员同事的话来说,除了一些在客户端进行布局的DOM元素之外,几乎不会使用ID来控制样式。就我们工作的结果来看,不规则的ID也并没有造成任何的影响。

 

相关文章:

为WebForms说几句话,以及一些ASP.NET开发上的经验(1):ViewState、性能

为WebForms说几句话,以及一些ASP.NET开发上的经验(3):生成复杂的ID难以使用JavaScript操作

未完待续:

五、MVC

六、单元测试

Feedback

#1楼    回复  引用  查看    

2007-12-22 22:48 by wit      
沙发,大哥有文采哈!

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

2007-12-22 22:48 by Jeffrey Zhao      
从五点断断续续写到现在,写这样的文章真是费神……

#3楼    回复  引用  查看    

2007-12-22 22:49 by wit      
辛苦了,你的文章咱都看,看着惬意!

#4楼    回复  引用  查看    

2007-12-22 22:51 by SZW      
那么我想说,ViewState、PostBack、GridView远不是WebForms的全部
=================================
要命了,我也是这么想的,为什么大家就一看到MVC和WebForms就以为我一定要反对WebForm呢

补充一下,我说ViewState、PostBack和客户端有关情况,似乎也没说WebForm别的什么了,哈

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

2007-12-22 22:56 by Jeffrey Zhao      
@SZW
我没说你反对阿,只是在有些问题上有点分歧,呵呵。:)

#6楼    回复  引用  查看    

2007-12-22 22:56 by birdshome      
目前WebForm在前端开发中一个比较郁闷的问题就是ID污染,WebForm框架中为了避免命名冲突,使用container Id嵌套拼接的方式从根本上杜绝了冲突,但也使得id在客户端引用变得非常困难。虽然我们知道Page类上提供了获取Client Id的属性,但是这样一来的问题就是JavaScript代码必须和C#耦合在一起,使得前端脚本代码的内聚性几乎消失掉了:(

#7楼    回复  引用  查看    

2007-12-22 22:57 by SZW      
@Jeffrey Zhao
--引用--------------------------------------------------
Jeffrey Zhao: @SZW
我没说你反对阿,只是在有些问题上有点分歧,呵呵。:)
--------------------------------------------------------
我已经明白你的意思了,其实很多地方我们是有共识的,关键是我们的一番对话引发了好多人“跟潮”了,我也很郁闷

#8楼    回复  引用  查看    

2007-12-22 22:57 by Anders Cui      
不错,从文中也可看到不少人对WebForms反感,其实是基于一些误解。博客园社区也是使用WebForms的一个好例子吧,期待老赵的下一篇!

#9楼    回复  引用  查看    

2007-12-22 23:00 by SZW      
@birdshome
--引用--------------------------------------------------
birdshome: 目前WebForm在前端开发中一个比较郁闷的问题就是ID污染,WebForm框架中为了避免命名冲突,使用container Id嵌套拼接的方式从根本上杜绝了冲突,但也使得id在客户端引用变得非常困难。虽然我们知道Page类上提供了获取Client Id的属性,但是这样一来的问题就是JavaScript代码必须和C#耦合在一起,使得前端脚本代码的内聚性几乎消失掉了:(
--------------------------------------------------------
对于你说的ID污染问题,有时候我已经用CSS替代,毕竟Css返回是不会变的(我通常和jQuery一起用,所以和ID几乎没有区别,甚至可以多个对象一起控制)

@Jeffrey Zhao
GridView的客户端代码有时候确实比较烦人,以前迫不得已做了这个插件:希望给点建议:http://www.cnblogs.com/szw/archive/2007/12/17/1002975.html

希望以后这样繁琐的事情可以少发生一点

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

2007-12-22 23:02 by Jeffrey Zhao      
--引用--------------------------------------------------
birdshome: 目前WebForm在前端开发中一个比较郁闷的问题就是ID污染,WebForm框架中为了避免命名冲突,使用container Id嵌套拼接的方式从根本上杜绝了冲突,但也使得id在客户端引用变得非常困难。虽然我们知道Page类上提供了获取Client Id的属性,但是这样一来的问题就是JavaScript代码必须和C#耦合在一起,使得前端脚本代码的内聚性几乎消失掉了:(
--------------------------------------------------------
我觉得不规则的ID反而让前端脚本代码不得不做到内聚……下一片我就会讲到这点,我觉得并没有太大问题啊,呵呵……

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

2007-12-22 23:02 by Jeffrey Zhao      
--引用--------------------------------------------------
SZW:
我已经明白你的意思了,其实很多地方我们是有共识的,关键是我们的一番对话引发了好多人“跟潮”了,我也很郁闷
--------------------------------------------------------
还是不错的啊,希望能让更多有思考,呵呵。

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

2007-12-22 23:03 by Jeffrey Zhao      
--引用--------------------------------------------------
SZW:
@Jeffrey Zhao
GridView的客户端代码有时候确实比较烦人,以前迫不得已做了这个插件:希望给点建议:http://www.cnblogs.com/szw/archive/2007/12/17/1002975.html

希望以后这样繁琐的事情可以少发生一点
--------------------------------------------------------
所以我从来不用GridView,真的是一点不用。

#13楼    回复  引用  查看    

2007-12-22 23:06 by SZW      
@Jeffrey Zhao
我也在恢复里说了这样的争论还是有它的价值的,至少还能感受到.NET亲友团的强大。

只是讨论的主题似乎偏离我的初衷了,哈哈

#14楼    回复  引用  查看    

2007-12-22 23:07 by SZW      
@Jeffrey Zhao
--引用--------------------------------------------------
所以我从来不用GridView,真的是一点不用。
--------------------------------------------------------
可能这也是我们在应用环境上产生的差异,有时候,大量的报表(Table格式),让我不得不去使用GridView,要是以前的ASP那我也死心了

#15楼    回复  引用  查看    

2007-12-22 23:10 by SZW      
@Jeffrey Zhao
顺便向老赵讨论个问题,如果if{}else{}判断比较繁琐的话,值不值得用try{}catch{}来(if里面可以报错)?很久前就想找人讨论一下,今天突然又碰到了才想起来

补充说明一下:if里面也不是相当繁琐,用了if就可以避免报错,老赵有碰到过吗?

#16楼    回复  引用  查看    

2007-12-22 23:10 by 阿不      
如果只是在展示方面,GridView真的是一点意义都没有。
另外,我们这边是否还可以再说一下DataSourceControl
利用DataSourceControl可以减少我们太多的麻烦了。
我认为使用DataSourceControl就是一种Best Practice。不仅是已有的ObjectDataSource,还包括我们可以自己写的。

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

2007-12-22 23:11 by Jeffrey Zhao      
--引用--------------------------------------------------
SZW: @Jeffrey Zhao
可能这也是我们在应用环境上产生的差异,有时候,大量的报表(Table格式),让我不得不去使用GridView,要是以前的ASP那我也死心了
--------------------------------------------------------
其实如果不用直接修改的话,也完全可以用Repeater或ListView来替代。
不过像你说的大都是报表的应用,对样式的要求可能不会太高吧。我是做互联网应用的,对界面的要求是非常高的,但是没有太多表格数据。

#18楼    回复  引用  查看    

2007-12-22 23:12 by 阿不      
@SZW
我个人认为不值得,我们大多数人情况宁愿多一些判断来减少异常出现的可能。

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

2007-12-22 23:13 by Jeffrey Zhao      
@SZW
一般不要用try...catch...来控制逻辑,因为会大大降低性能——不过应该也不会成为性能瓶颈。
我还是建议不建议用try...catch来控制逻辑,因为if的话清楚吧,每个条件都是明确的,用try...catch别人还要去看到底什么情况下会抛出异常……

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

2007-12-22 23:14 by Jeffrey Zhao      
--引用--------------------------------------------------
阿不: @SZW
我个人认为不值得,我们大多数人情况宁愿多一些判断来减少异常出现的可能。
--------------------------------------------------------
还有一点就是,用if...else能够隐藏将会抛出的异常细节。这也是在catch里处理后再抛出的原因,呵呵。

#21楼    回复  引用  查看    

2007-12-22 23:15 by stonezhu      
"四、生成的ID难以使用JavaScript操作"
这个到是的,不过只要好好了解一下ASP.NET ID的生成规则,还是可以用Javascript去很好的控制的。如usercontrol前面他会加上usercontrol的ID加_再加你usercontrol的id。
还有我觉得在用asp.net 的时候,在aspx里面直接调用cs里面的function还是非常方便的。

#22楼    回复  引用  查看    

2007-12-22 23:16 by SZW      
@阿不
恩,我举个我实际碰到的例子:当用if/else可以避免异常,如果不用if,如果数据库返回值是null就会产生异常。

这时候,我用if控制的话,只就流程上来说,会比较低效。
如果用try,可以减少很多判断,让他在null的时候,执行我if里面的。

注:这种方法很多时候if对应catch,else对应try内的内容

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

2007-12-22 23:16 by Jeffrey Zhao      
--引用--------------------------------------------------
阿不: 如果只是在展示方面,GridView真的是一点意义都没有。
另外,我们这边是否还可以再说一下DataSourceControl
利用DataSourceControl可以减少我们太多的麻烦了。
我认为使用DataSourceControl就是一种Best Practice。不仅是已有的ObjectDataSource,还包括我们可以自己写的。
--------------------------------------------------------
我不用DataSourceControl的,因为开发复杂,而且感觉难以应对复杂的业务逻辑,就像ObjectDataSource就比较死板,应用不多……不知道是我没有不了解得结果。

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

2007-12-22 23:17 by Jeffrey Zhao      
--引用--------------------------------------------------
stonezhu: "四、生成的ID难以使用JavaScript操作"
这个到是的,不过只要好好了解一下ASP.NET ID的生成规则,还是可以用Javascript去很好的控制的。如usercontrol前面他会加上usercontrol的ID加_再加你usercontrol的id。
还有我觉得在用asp.net 的时候,在aspx里面直接调用cs里面的function还是非常方便的。
--------------------------------------------------------
那太麻烦了,也不是我下面要写的内容的本意啊,呵呵。而且一个好的控件,应该不用知道自己的父控件是什么的,这样才有被广泛使用的意义。

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

2007-12-22 23:18 by Jeffrey Zhao      
--引用--------------------------------------------------
SZW: @阿不
恩,我举个我实际碰到的例子:当用if/else可以避免异常,如果不用if,如果数据库返回值是null就会产生异常。

这时候,我用if控制的话,只就流程上来说,会比较低效。
如果用try,可以减少很多判断,让他在null的时候,执行我if里面的。

注:这种方法很多时候if对应catch,else对应try内的内容
--------------------------------------------------------
如果从性能上讲的话,一次catch的性能损失可以抵得了无数次if了(条件太复杂的condition不算,呵呵)……

#26楼    回复  引用  查看    

2007-12-22 23:19 by SZW      
@Jeffrey Zhao
--引用--------------------------------------------------
其实如果不用直接修改的话,也完全可以用Repeater或ListView来替代。
不过像你说的大都是报表的应用,对样式的要求可能不会太高吧。我是做互联网应用的,对界面的要求是非常高的,但是没有太多表格数据。
--------------------------------------------------------

我说的报表除了“财务报表”那种直接用来看的,还会涉及到一些操作,一些ItemCommand等等,这些是必须要产生ViewState的,所以我对这个简直是……(还是不要说出来了)

#27楼    回复  引用  查看    

2007-12-22 23:22 by Nathan 暴      
写的真好,我也是觉得Gridview太过复杂了,多数情况都用Repeater。还有老赵认为,数据库的交互是影响网站性能的主要因素之一,深表赞同。

#28楼    回复  引用  查看    

2007-12-22 23:22 by SZW      
@Jeffrey Zhao
恩,我明白了,谢谢!只是有时候一个页面我要通过SQL+XML同时控制若干个(客户决定)自动生成的控件(他们的所有属性我也都要完全控制),对应的判断可能会非常多,而且很多是客户端过滤不掉的,所以往往是if里面本来就很复杂了,里面还要套if,那些情况switch还用不上

#29楼    回复  引用  查看    

2007-12-22 23:23 by stonezhu      
by the way,
老赵下次可否好好聊一下关于缓存?觉得你写文章非常透彻,错了,应该是你理解的很透彻,所以才能写的透彻。
我一直对缓存不是很理解,如缓存的过期规则,怎么才能灵活控制,灵活控制数据库里面的数据更新了,缓存更新。(SQL 可以支持,但是其它的可否支持,可以不通过SQL的支持来实现缓存的更新控制,这我很长时间没有搞明白),还是就是文本控制,通过文体的改变通知缓存来更新,但是存数据库的怎么来结合这样的做法。我也搞的糊里糊涂的......
SOS 老赵.

#30楼    回复  引用  查看    

2007-12-22 23:25 by SZW      
缓存确实也是.NET3.5值得关注的一个方面,支持stonezhu ^_^

#31楼    回复  引用  查看    

2007-12-22 23:25 by stonezhu      
--引用--------------------------------------------------
Jeffrey Zhao: --引用--------------------------------------------------
stonezhu: "四、生成的ID难以使用JavaScript操作"
这个到是的,不过只要好好了解一下ASP.NET ID的生成规则,还是可以用Javascript去很好的控制的。如usercontrol前面他会加上usercontrol的ID加_再加你usercontrol的id。
还有我觉得在用asp.net 的时候,在aspx里面直接调用cs里面的function还是非常方便的。
--------------------------------------------------------
那太麻烦了,也不是我下面要写的内容的本意啊,呵呵。而且一个好的控件,应该不用知道自己的父控件是什么的,这样才有被广泛使用的意义。
--------------------------------------------------------
如果不是,可以做的更为通过,那是非常期待老赵下一篇的精彩文章啦.

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

2007-12-22 23:26 by Jeffrey Zhao      
--引用--------------------------------------------------
SZW:
@Jeffrey Zhao
我说的报表除了“财务报表”那种直接用来看的,还会涉及到一些操作,一些ItemCommand等等,这些是必须要产生ViewState的,所以我对这个简直是……(还是不要说出来了)
--------------------------------------------------------
那么用MVC对这点有帮助吗?

#33楼    回复  引用  查看    

2007-12-22 23:28 by aspnetx      
对于做BI的应用系统来说,webform还是可以让我吃尽甜头的
我想关键还是看行业应用吧,真正的企业级业务系统恐怕真的很难容忍webform,就目前的情况来看.
另外,asp.net的版本也已经过三了,是否会和当年asp一样的套路呢,MVC的出现是否说明了什么?
难道以后所谓的webform与MVC并存难道就是现在微软所宣称的asp.net与asp并存吗?关键还是看看待问题的角度了,从商业角度这么说没什么问题,但是从技术角度从技术人员群体来说恐怕就很难达成一致了.

#34楼    回复  引用    

2007-12-22 23:30 by 一见你就笑 [未注册用户]
你说你抛弃了DATASET跟DATATABLE..那要怎么做呢..
谢谢(:

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

2007-12-22 23:30 by Jeffrey Zhao      
--引用--------------------------------------------------
stonezhu: by the way,
老赵下次可否好好聊一下关于缓存?觉得你写文章非常透彻,错了,应该是你理解的很透彻,所以才能写的透彻。
我一直对缓存不是很理解,如缓存的过期规则,怎么才能灵活控制,灵活控制数据库里面的数据更新了,缓存更新。(SQL 可以支持,但是其它的可否支持,可以不通过SQL的支持来实现缓存的更新控制,这我很长时间没有搞明白),还是就是文本控制,通过文体的改变通知缓存来更新,但是存数据库的怎么来结合这样的做法。我也搞的糊里糊涂的......
SOS 老赵.
--------------------------------------------------------
我在目前的项目里使用了一种基于事件的过期机制。其实这点是比较常见的模式吧,有机会我写一下。
还有我不懂如何进行“文本(文体?)控制”,我没有听说过这个唉。

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

2007-12-22 23:31 by Jeffrey Zhao      
--引用--------------------------------------------------
SZW: 缓存确实也是.NET3.5值得关注的一个方面,支持stonezhu ^_^
--------------------------------------------------------
.NET 3.5对于缓存有什么新的功能吗?

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

2007-12-22 23:32 by Jeffrey Zhao      
--引用--------------------------------------------------
stonezhu:如果不是,可以做的更为通过,那是非常期待老赵下一篇的精彩文章啦.
--------------------------------------------------------
客气,有了经验之后写这些内容只是简单的“倒出来”而已。:)

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

2007-12-22 23:33 by Jeffrey Zhao      
--引用--------------------------------------------------
aspnetx: 对于做BI的应用系统来说,webform还是可以让我吃尽甜头的
我想关键还是看行业应用吧,真正的企业级业务系统恐怕真的很难容忍webform,就目前的情况来看.
另外,asp.net的版本也已经过三了,是否会和当年asp一样的套路呢,MVC的出现是否说明了什么?
难道以后所谓的webform与MVC并存难道就是现在微软所宣称的asp.net与asp并存吗?关键还是看看待问题的角度了,从商业角度这么说没什么问题,但是从技术角度从技术人员群体来说恐怕就很难达成一致了.
--------------------------------------------------------
我一直搞不懂,为什么企业级业务系统很难容忍webform呢?它们的特点究竟是什么呢?

#39楼    回复  引用    

2007-12-22 23:34 by jt [未注册用户]
好文,非常看好你的做法,尤其是和领域对象结合的地方

不过有个问题,每次load的时候都要bind把?和gridview禁用viewstate也一样吧

#40楼    回复  引用  查看    

2007-12-22 23:34 by 伍迷      
目前最缺的就是这样极具有经验总结后的应用文章,感谢老赵的分享。

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

2007-12-22 23:34 by Jeffrey Zhao      
--引用--------------------------------------------------
一见你就笑: 你说你抛弃了DATASET跟DATATABLE..那要怎么做呢..
谢谢(:
--------------------------------------------------------
我一般只用DataReader,表现层只绑定Domain Model,文章里也写过了。

#42楼    回复  引用  查看    

2007-12-22 23:35 by stonezhu      
@Jeffrey Zhao
啊,哈哈,“文本(文体?)控制”,不好意思,就是根据文件的修改时间来控制,不好意思,手快了不知道在写什么了。
非常谢谢你谈谈缓存控制啊。
就是不知道是什么时候哦,我想大家也是非常想看看老赵聊缓存哦:-D

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

2007-12-22 23:35 by Jeffrey Zhao      
--引用--------------------------------------------------
jt: 好文,非常看好你的做法,尤其是和领域对象结合的地方

不过有个问题,每次load的时候都要bind把?和gridview禁用viewstate也一样吧
--------------------------------------------------------
如果要使用GridView的复杂事件,那么要么开启ViewState,要么在Page_Load里再绑定一把。

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

2007-12-22 23:39 by Jeffrey Zhao      
--引用--------------------------------------------------
stonezhu: @Jeffrey Zhao
啊,哈哈,“文本(文体?)控制”,不好意思,就是根据文件的修改时间来控制,不好意思,手快了不知道在写什么了。
非常谢谢你谈谈缓存控制啊。
就是不知道是什么时候哦,我想大家也是非常想看看老赵聊缓存哦:-D
--------------------------------------------------------
哦,原来是这个啊……其实这点还是比较容易相通的吧,就是在该过期的时候修改某个文本文件,然后其它线程就可以通过判断修改时间来知道是否会过期了。
最近比较忙,我也很久没有写了,今天比较空就写得多了点,明天还要处理工作上的事情呢。创业的时候,每一天都能是休息天,但每天也都可能是工作日……

#45楼    回复  引用    

2007-12-22 23:39 by jt [未注册用户]
我想你是想结合ddd和webform,做法挺好,我要借鉴.

交流的确有帮助,我对webform有所改观,谢谢你 老赵,呵呵

#46楼    回复  引用    

2007-12-22 23:41 by jt [未注册用户]
this.GetImagePath(Container.DataItem)
---------------
container要是范型实现就更好了,就不用转型了

#47楼    回复  引用  查看    

2007-12-22 23:45 by aspnetx      
@Jeffrey Zhao
我一直搞不懂,为什么企业级业务系统很难容忍webform呢?它们的特点究竟是什么呢?
------------------------------------
其实,我完全同意赵哥文章里的观点,要不然咱也不能一直这么的支持微软对吧?但是,当看到身边的很多业务系统,没有一个是webform时,甚至没有一个是asp.net时,或者没有一个是.net时,甚至你的老板找你谈话你不转j2ee你就离职的时候时,咱们会是什么心情呢?
微软在中国大陆的销售份额很低,所以对于类似的技术推广投入不是很大,这个咱们不提,因为也不是咱们关心的事,咱们的想法左右不了microsoft的DPE.不过,事实是什么呢?就我所接触的派出所相关业务,从户政到行政案件到刑侦案件到110接处警,没见过一个架构师敢在.net头上动土的,我自己都不愿意接受这样一个现实.
说多了全是牢骚,牢骚发过了,那就好,咱该干啥还干啥去,呵呵,赵哥晚安了先.

#48楼    回复  引用  查看    

2007-12-22 23:46 by stonezhu      
@Jeffrey Zhao
哦?老赵已经开始创业啦?没听你说过嘛,还是我没有看到啊?
如果是的,预祝你创业成功!
现在园子里面创业的人越来越多了,包括我
也正在奋斗着.......

#49楼    回复  引用  查看    

2007-12-22 23:46 by SZW      
@Jeffrey Zhao
--引用--------------------------------------------------
Jeffrey Zhao: --引用--------------------------------------------------
SZW:
@Jeffrey Zhao
我说的报表除了“财务报表”那种直接用来看的,还会涉及到一些操作,一些ItemCommand等等,这些是必须要产生ViewState的,所以我对这个简直是……(还是不要说出来了)
--------------------------------------------------------
那么用MVC对这点有帮助吗?
--------------------------------------------------------


MVC至少以“指令性”的URL替代了我们PostBack回去的ItemCommandName,至于数据,MVC是不直接处理页面数据的(这也是MVC不是用ViewState的原因),在Controller里面直接处理,效率上来说,反正每次都是要读数据库,所以剩下来的时间就是数据传输了。

因为我十分……ViewState,所以通常我还是回去避免,比如专门传入一个Action=bl&id=xx到某个页面,负责处理,但这样其实维护很麻烦,而MVC其实就已经(顺带)解决了这个问题

#50楼    回复  引用  查看    

2007-12-22 23:49 by Anders Cui      
--引用--------------------------------------------------
SZW: @Jeffrey Zhao
顺便向老赵讨论个问题,如果if{}else{}判断比较繁琐的话,值不值得用try{}catch{}来(if里面可以报错)?很久前就想找人讨论一下,今天突然又碰到了才想起来

补充说明一下:if里面也不是相当繁琐,用了if就可以避免报错,老赵有碰到过吗?
--------------------------------------------------------
这种情况下,最好不要用try/catch,首先是异常所带来的性能问题;其次,我感觉异常通常用于报告API的用户输入值的无效;另外,try会隐藏很多问题,异常可能是数据库返回null引起的,也有可能不是。

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

2007-12-22 23:54 by Jeffrey Zhao      
--引用--------------------------------------------------
jt: 我想你是想结合ddd和webform,做法挺好,我要借鉴.

交流的确有帮助,我对webform有所改观,谢谢你 老赵,呵呵
--------------------------------------------------------
其实.net并没有影响任何开发方式设计模式等等,它的基础不比Java差,可能在这个基础上所产生的框架少了一些(不过也慢慢好起来的阿)。:)

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

2007-12-22 23:55 by Jeffrey Zhao      
--引用--------------------------------------------------
aspnetx:
其实,我完全同意赵哥文章里的观点,要不然咱也不能一直这么的支持微软对吧?但是,当看到身边的很多业务系统,没有一个是webform时,甚至没有一个是asp.net时,或者没有一个是.net时,甚至你的老板找你谈话你不转j2ee你就离职的时候时,咱们会是什么心情呢?
微软在中国大陆的销售份额很低,所以对于类似的技术推广投入不是很大,这个咱们不提,因为也不是咱们关心的事,咱们的想法左右不了microsoft的DPE.不过,事实是什么呢?就我所接触的派出所相关业务,从户政到行政案件到刑侦案件到110接处警,没见过一个架构师敢在.net头上动土的,我自己都不愿意接受这样一个现实.
说多了全是牢骚,牢骚发过了,那就好,咱该干啥还干啥去,呵呵,赵哥晚安了先.
--------------------------------------------------------
原来是这个原因啊……唉还是互联网应用来的纯粹。