Asp.net Mvc Framework 十一 (自定义Helper在MVC中的使用)

Monorail中的Helper是绑定在Controller上的
形如:
[Helper(typeof(ChHelper))]
abstract public class BaseBlockController : SmartDispatcherController{
}
但本身Helper是使用在View中的,所以 Monorail这种定义方式 略微违背了分离之道

那么Asp.net MVC中是如何绑定自定义的Helper的呢?

其实Asp.net MVC的View也有代码文件即类似 index.aspx.cs
代码文件继承于ViewPage

下面用一个实例来讲
我首先我自定义一个Helper
实现了对字符串的一些小扩展
public class StringHelper
{
    
public string Red(string str) {
        
return string.Format(@"<span style=""color:red"">{0}</span>",str);
    }

    
public string Green(string str) {
        
return string.Format(@"<span style=""color:green"">{0}</span>", str);
    }

}
那么我们怎样才能在View使用它呢?
我们可以在View的cs中写以下代码
        public StringHelper Str {
            
get;
            
set;
        }
即为
public partial class Index : ViewPage
    
{
        
public StringHelper Str {
            
get;
            
set;
        }

    }


这样我们就可以在View中使用
<%=Str.Red(ViewData["title"])%>
这样的代码了

如果这个Helper你想不仅在此一个文件中使用
那么可以通过将属性 写在一个BaseViewPage的基类中 然后所有的View都继承于自定义的BaseViewPage来实现

同样的,Master文件中也可以通过类似的方法来完成使用自定义的Helper
0
0
(请您对文章做出评价)
« 上一篇:Asp.net Mvc Framework 十(测试方法及Filter的示例)
» 下一篇:用于样式检测的临时日志(81211bd6-b96d-4c80-98d5-dc709e5d7811 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)
posted @ 2008-03-22 10:00 重典 阅读(3324) 评论(27)  编辑 收藏 网摘 所属分类: ASP.NET MVC

  回复  引用  查看    
#1楼2008-03-22 14:59 | SZW      
public static class StringHelper
{
public static string Red(this string str) {
return string.Format(@"<span style=""color:red"">{0}</span>",str);
}
}


<%= ViewData["title"].ToString().Red()%>

另外其实这个方法不是可以在ASP.NET MVC提供的HTMLHelper中重写增加吗?

  回复  引用  查看    
#2楼[楼主]2008-03-22 15:24 | 重典      
@SZW
是的方法是可以的,这里只是单纯的介绍自己写Helper的方法,例子是匆忙之间想到的,未必帖切
是可以用Extension来做到HtmlHelper中的

  回复  引用  查看    
#3楼2008-03-22 16:21 | Jeffrey Zhao      
文章说的方法侵入性比较高,要求View都继承一个新的Page。
其实可以多多利用Extension Method,例如文章里的做法。

public static StringHelper StringHelper(this Page page)
{
return new StringHelper();
}

这样代码里可以写:
StringHelper().XXX。

  回复  引用  查看    
#4楼[楼主]2008-03-22 16:29 | 重典      
@Jeffrey Zhao
赵兄说的没错,这样做的确是进行扩展Helper的一种有效方法

但我感觉扩展方法有些时候毕竟有其不足
比如语义环境所限,我要自定义的Helper可能不是 Html Url Ajax中的任何一个,
如果我扩展到这些Helper中,会引起一些误会

还有就是Helper中有属性或集合,这时Extension就无能为力了

继承的确是不可取的一种方法 当然如果从组合优于继承的角度讲

在每一个ViewPage里写一个StringHelper的属性是最好的

但是这样做代码量也是不小的.

如果赵兄有更好的方法,希望一起研究^^

  回复  引用  查看    
#5楼2008-03-22 17:46 | Jeffrey Zhao      
@重典
只要让扩展Page的方法返回我们的Helper类,所有的功能都是实现在Helper类中,不会出现属性,集合无法实现的问题的。

  回复  引用  查看    
#6楼[楼主]2008-03-22 19:09 | 重典      
@Jeffrey Zhao
您指的是类似于这样的吧
class HelperExtension {
public static StringHelper(this ViewPage v){
return new StringHelper();
}
}

我总是感觉使用方法实现不如属性的优美,呵呵

  回复  引用  查看    
#7楼2008-05-01 15:23 | 土星的狗狗      
Coder == Actor
  回复  引用  查看    
#8楼2008-07-31 16:11 | 孤独客      
收益匪浅
从LZ的文章中,更从各位的讨论中 :-)

  回复  引用  查看    
#9楼2008-08-30 18:19 | 勇敢的兽      
大部分的Helper都是基于string的吗?例如通过HtmlHelper的方法DropDownList(),生成一个<select>...</select>的字符串然后输出到页面中

如果我要重新封装componentart.web.ui中的Calendar控件,作为我自己的自定义服务器端控件,该如何操作才能实现

<%=MyControl.Calendar("calendarID")%>


  回复  引用  查看    
#10楼[楼主]2008-08-30 18:24 | 重典      
那就要重新写过了,不能用原来的方法了,因为原来的是用的Control类的Render来显示的,这里要用字符串
  回复  引用  查看    
#11楼[楼主]2008-08-30 18:24 | 重典      
@勇敢的兽
那就要重新写过了,不能用原来的方法了,因为原来的是用的Control类的Render来显示的,这里要用字符串

  回复  引用  查看    
#12楼2008-08-30 18:25 | 勇敢的兽      
在很多自己定义的控件或者方法的时候

如LZ所说先自己写一个BaseViewPage,继承MVC.ViewPage,然后自己项目中的所有Page都继承BaseViewPage,不失为一个好方法。

有没有更好的方法呢?

  回复  引用  查看    
#13楼[楼主]2008-08-30 18:36 | 重典      
扩展方法 类似
static public class Include {
static public string Script(this HtmlHelper h, String fn) {
if (!fn.StartsWith("/"))
fn = string.Format("{0}Javascript/{1}.js", SiteConfig.Current.Path, fn.TrimEnd(".js".ToCharArray()));

return
string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>"
, fn);
}
static public string CSSLink(this HtmlHelper h, String fn) {
return string.Format(
"<link href=\"{0}Style/{1}/{2}.css\" rel=\"stylesheet\" type=\"text/css\" />"
, SiteConfig.Current.Path
, SiteConfig.Current.Style
, fn.TrimEnd(".css".ToCharArray())
);
}
}

我将这2个方法扩展到了HtmlHelper

<%=Html.CSSLink("friend")%>
<%=Html.Script("Profile")%>
就用了

  回复  引用  查看    
#14楼2008-08-30 18:37 | 勇敢的兽      
http://www.codeproject.com/KB/aspnet/asp-net-mvc-calendar.aspx

找到一个用于MVC的Calendar,先学习一下,我用的Calendar一个TextBox显示日期,一点TextBox才弹出日历的,所以看来还是只有自己写了,多谢重典大哥哈,真真是明灯一盏

  回复  引用  查看    
#15楼2008-08-30 18:39 | 勇敢的兽      
呃,弱弱的问一句,怎么“扩展到了HtmlHelper” 去呢??
  回复  引用  查看    
#16楼[楼主]2008-08-30 18:45 | 重典      
@勇敢的兽
是C#3.0的新特性叫扩展方法

  回复  引用  查看    
#17楼2008-08-30 18:53 | 勇敢的兽      
啊,原来是这样的啊

MVC源码中Extensions文件夹里面的全是用这种扩展的方法扩的类,我模仿学习一下

  回复  引用  查看    
#18楼[楼主]2008-08-30 19:01 | 重典      
@勇敢的兽
是的,它自己也是这么用的

还有第二种方法就是生成自定义模板,不过限制太多,不推荐使用

  回复  引用  查看    
#19楼2008-08-30 19:12 | 勇敢的兽      
又要麻烦你了
新增类在我自己的项目里
namespace System.Web.Mvc
{
static public class Extensions
{
static public string Test(this HtmlHelper h)
{
return "Hello";
}

static public string Test(this HtmlHelper h, string s)
{
return "Hello: " + s;
}
}
}

================================
aspx中调用
<%=Html.Test()%>
================================
报错

System.Web.HttpCompileException: e:\Project\MyMVCTest\Views\Customer\List.aspx(6): error CS0012: 类型“System.Web.Mvc.Controller”在未被引用的程序集中定义。必须添加对程序集“System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”的引用。


包括我调用MVC源码中提供的CheckBox(<%=Html.CheckBox(...)%>)
也会出现这样的错误


  回复  引用  查看    
#20楼2008-08-30 19:13 | 勇敢的兽      

<%=Html.DropDownList("CustomerID") %>

这样的就不会错

  回复  引用  查看    
#21楼[楼主]2008-08-30 19:19 | 重典      
@勇敢的兽
你是不是用的preview4啊,卸载后安装preview5试试

  回复  引用  查看    
#22楼2008-08-30 19:31 | 勇敢的兽      
嗯,确实是preview4,我加载preview4源码作为附加项目编译通过的

preview4就不行?

  回复  引用  查看    
#23楼[楼主]2008-08-30 19:39 | 重典      
System.Web.Mvc, Version=1.0.0.0是pv5
System.Web.Mvc, Version=0.0.0.0是pv4
重新引用一下那几个文件应该也能正常使用

  回复  引用  查看    
#24楼2008-08-30 19:41 | 勇敢的兽      
查看后发现 System.Web.Mvc, Version=1.0.0.0



还是没有找到错误的原因

  回复  引用  查看    
#25楼[楼主]2008-08-30 19:49 | 重典      
@勇敢的兽
重新引用那几个mvc包含的文件

  回复  引用  查看    
#26楼2008-08-30 19:54 | 勇敢的兽      
嗯,重新引用了System.Web.Mvc 就可以了CheckBox可以,自己定义的Test()也可以

但是为什么我引用他的源码项目编译的就不行呢...下载的是Preview4的源码啊,本来想附加源码在调试的时候可以跟踪进去多学习一下的

谢谢你

  回复  引用  查看    
#27楼2008-08-30 19:55 | 勇敢的兽      
得吃饭了....人是肉做的,饭是超市买的的,我不是传说中的铁做的...饭也不是传说中钢铁厂出来的