动态网页的历史非常悠久,可以追溯到上个世纪。就技术类型而言,主要有 ASP 、PHP 、 JSP 三大派。笔者接触过 ASP 、 PHP ,遗憾的是几乎从未接触过 JSP 。偶就天生不是 JAVA 语系的。
后来,笔者稍微远离了一下 Web 开发, Web 发生了翻天覆地的变化, css 成了布局主流, ASP.NET 冒出来了。这使得笔者不得不在 2008 、 2009 年间重新进入 Web 开发领域。然后,自认为已经跟上时代了,于是又稍微远离了 Web 开发。短短两三年,PHP 几乎啥也没变, HTML 基本未变(虽然冒出了个 HTML5 ),但 ASP.NET 却发生了翻天覆地的变化:官方 MVC 框架的推出,使得 ASP.NET 再也不用使用很别扭的服务端控件了,将自由操控 HTML 的权利还给了开发者(然而,却剥夺了自由操控 URL 的权利)。
下面,笔者以写一个搜索引擎为例,带大家进入 ASP MVC 框架的世界。
建立项目
如下图,在 VS2012 中建立一个 ASP.NET MVC4 Web Application :
然后选 Basic 吧:
试图引擎按默认选择 Razor 吧。
建好之后,我们将看到如下的项目结构:
其中 Views 放各种页面, Content 放 css 啥的, Controllers 放“控制器”代码,Models 里放各种业务模型的数据结构定义。
URL 规划
这个 MVC 框架的一个越俎代庖的事情就是接管了 URL 路由。嗯,其实也蛮方便的,叫越俎代庖有点过了,仁者见仁智者见智吧。
打开 RouteConfig.cs ,我肯可以看到:
public RouteConfig { public static void RegisterRoutes( RouteCollection routes) { routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
routes.MapRoute( name: "Default" , url: "{controller}/{action}/{id}" , defaults: new { controller = "Home" , action = "Index" , id =UrlParameter .Optional } ); } } |
这里有个默认的路由。比如一段 http://www.xxx.com/a/b/c/ ,按照这个 route 的解释, a 就是 controller 的名字, b 就是 action 的名字, c 就是 id 的名字。如果访问http://www.xxx.com/a/ ,那么 a 是 controller 的名字, action 和 id 未给出,就按照default 中的设定, action 为 Index , id 为空。
说到这里,还没解释 action 是啥, id 是啥呢。按照我们很久以前的 url 规划习惯,经常有 article.aspx?action=modify&id=1 这样子的 url , controller 的概念就是这里的acticle.aspx ,表示文章处理的页面 / 模块; action 就是 url 的 query string 中的 action,一个处理模块通常由多个功能, action 参数告诉它现在需要处理什么; id 含有通常是跟随 action 而定的,比如刚才的例子, id 表示要处理哪篇文章。
我们规划搜索引擎的 URL 吧:
路径 | 页面内容 |
/ | 首页 |
/keyword | 搜索结果页 |
于是我们可以将上面的路由代码改为:
public RouteConfig { public static void RegisterRoutes( RouteCollection routes) { routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
routes.MapRoute( name: "HomePage" , url: "" , defaults: new { controller = "Home" , action = "Index" } );
routes.MapRoute( name: "SearchResult" , url: "{keyword}" , defaults: new { controller = "Home" , action = "Search" , keyword = UrlParameter .Optional } ); } } |
注意,我们使用了一个名为 Home 的 controler ,以及名为 Index 、 Search 的两个action , Search 这个 action 带参数 keyword 。
建立相应的代码和页面
建立 controller
右键单击 Controllers 目录,选择 Add=>Controller :
输入名字 HomeController ,选择模版类型为 Empty MVC controller :
注意,必须使用这个名字!因为我们之前在 URL 路由中设置的 Controller 名字是Home 。
建好后得到一个比较简单的代码,将其改造成如下的样子:
public class HomeController : Controller { // // GET: /
public ActionResult Index() { return View(); }
// // GET: /keyword
public ActionResult Search( string keyword) { return View(); } } |
建立 View
右键单击 View 目录,新建子目录 Home (一定要与 controller 同名),然后右键单击Home 目录,选择 Add=>View :
名字改为 Index ,其余默认:
注意,必须为 Index ,与 action 保持同名。然后用同样方法建立一个 Search 页面。
到现在为止,我们的网站可以跑了!访问根目录:
访问搜索结果页面:
建立搜索结果
建立 model
考虑到搜索结果中, controller 处理后需要把结果传递给页面,我们建立一个 model类来表示这个数据结构。右键单击 Models 目录,新建一个 C# 代码文件,定义如下类型:
namespace SearchEngine.Models { public class SearchResultItem { public string Title { get ; set ; } public string Link { get ; set ; } public string Description { get ; set ; } }
public class SearchResult { public string Keyword { get ; set ; } public List < SearchResultItem > Results { get ; set ; } } } |
改造 controller
改写 controller 中的 Search 方法,改成:
public ActionResult Search( string keyword) { if (keyword == null ) { return RedirectToAction( "Index" ); }
Models. SearchResult result = new Models. SearchResult (); result.Keyword = keyword; result.Results = new List <Models. SearchResultItem >();
for ( int i = 0; i < 10; ++i) { Models. SearchResultItem item = new Models. SearchResultItem (); item.Link = "http://www.streamlet.org/" ; item.Title = " 溪流软件工作室 " ; item.Description = " 快来访问溪流软件工作室! " ;
result.Results.Add(item); }
return View(result); } |
注意,我们建立了数据 result ,通过 View(result) 传递给页面。
改造 View
改写 Search.cshtml ,改为:
@model SearchEngine.Models. SearchResult @{ ViewBag.Title = "Search" ; }
< h2 > Search </ h2 >
< p > 搜索 “ @ Model.Keyword” 的结果: </ p >
@ foreach ( var item in Model.Results) { < p > < a href =" @ item.Link " target ="_blank"> @ item.Title </ a >< br /> @ item.Description </ p > } |
第一行 @model 声明本页面的数据模型。后面 @ 开头的都是 C# 语句,剩余的是HTML 。大多数情况下, Razor 能识别 @ 的结束,这比 <% %> 、 <? ?> 书写起来都简洁一点。
再访问一下搜索结果页:
美化及搜索框处理
这部分利用 HTML 的知识和 PS 功底即可。我这里简单的放了一个 Logo 和搜索框。首页代码如下:
@{ ViewBag.Title = " 世界第一搜索引擎 " ; }
@ Styles .Render( "~/Content/Index.css" )
@section scripts { < script type ="text/javascript"> var search = function () { var keyword = $( "#keyword" ).val(); window.location = "/" + keyword; } </ script > }
< br /> < br /> < br /> < br /> < br /> < br /> < br />
< div id ="searchBox"> < img src ="~/Images/Logo.png" />< br /> < br /> < input id ="keyword" type ="text" /> < input id ="submit" type ="submit" value =" 搜索 " onclick =" javascript: search(); " /> </ div > |
页面效果如下:
搜索结果页面代码如下:
@model SearchEngine.Models. SearchResult @{ ViewBag.Title = "Search" ; }
@ Styles .Render( "~/Content/Search.css" )
@section scripts { < script type ="text/javascript"> var search = function () { var keyword = $( "#keyword" ).val(); window.location = "/" + keyword; } </ script > }
< div id ="searchBox"> < a href ="/">< img src ="~/Images/Logo.png" /></ a >< br /> < input id ="keyword" type ="text" value =" @ Model.Keyword " /> < input id ="submit" type ="submit" value =" 搜索 " onclick =" javascript: search(); " /> </ div >
< br />
@ foreach ( var item in Model.Results) { < p > < a href =" @ item.Link " target ="_blank"> @ item.Title </ a >< br /> @ item.Description </ p > }
|
页面效果如下:
无搜索数据时的处理
目前,我们在 Search 方法中生成的数据是假的。实际情况中要根据实际结果来。当没有数据的时候,我们要给出友好提示。
因此,将 controller 中 Search 方法改为:
public ActionResult Search( string keyword) { if (keyword == null ) { return RedirectToAction( "Index" ); }
Models. SearchResult result = new Models. SearchResult (); result.Keyword = keyword; result.Results = new List <Models. SearchResultItem >();
//for (int i = 0; i < 10; ++i) //{ // Models.SearchResultItem item = new Models.SearchResultItem(); // item.Link = "http://www.streamlet.org/"; // item.Title = " 溪流软件工作室 "; // item.Description = " 快来访问溪流软件工作室! ";
// result.Results.Add(item); //}
return View(result); } |
Search 页面相应地改为:
@model SearchEngine.Models. SearchResult @{ ViewBag.Title = "Search" ; }
@ Styles .Render( "~/Content/Search.css" )
@section scripts { < script type ="text/javascript"> var search = function () { var keyword = $( "#keyword" ).val(); window.location = "/" + keyword; } </ script > }
< div id ="searchBox"> < a href ="/">< img src ="~/Images/Logo.png" /></ a >< br /> < input id ="keyword" type ="text" value =" @ Model.Keyword " /> < input id ="submit" type ="submit" value =" 搜索 " onclick =" javascript: search(); " /> </ div >
< br />
@ if (Model.Results == null || Model.Results.Count() == 0) { < strong > 根据相关法律法规和政策,部分搜索结果未予显示。 </ strong > } else { foreach ( var item in Model.Results) { < p > < a href =" @ item.Link " target ="_blank"> @ item.Title </ a >< br /> @ item.Description </ p > } } |
页面效果:
例子代码: http://sdrv.ms/118Elro ( SearchEngine.rar )
演示页面: http://www.streamlet.org/Search/
原文章地址:http://www.cppblog.com/Streamlet/archive/2013/01/08/197092.html?utm_source=tuicool