教学帖:教你用简单的方法开发asp.net (二)

ktei2008 2013-09-02 09:59:21
加精
第一帖在这里:http://bbs.csdn.net/topics/390565621

废话不多说,紧接着上回继续。我们基本上已经搭起了整个项目的后台框架,甚至还写了一个非常简单测试。之后,我们又回顾了一点浅显的HTTP交互的基本知识。接下来,我们该讲一些跟Nancy相关的东西了。首先,我们从最简单的地方开始。

What exactly are we going to build?
很难在短短几个帖子里用一个复杂的项目来说明问题,我觉得学东西的时候,尤其对于初学者来说,例子越简单明了越好。我们的目标也很简单:就是做一个在线备忘录。基本流程大体是这样:用户登录以后,会显示出自己的所有备忘录链接。点击其中一个链接,可以看到该备忘录的详情。

关于MVC
有人可能会对Nancy本身的模式感兴趣——它是否是遵循MVC的?Nancy并不是一个MVC框架,它基本上就是一个路由+请求处理的精简框架。Nancy在模式方面不对你做任何限制,所以你当然可以按照MVC模式来走。在这篇教程里,我就不往MVC上靠了,因为太耗时间,信息量也太大,所以我们就充分利用Nancy的Module来进行开发吧。

NancyModule
打开你的IndexModule,你会看到这段代码:
public IndexModule()
{
Get["/"] = parameters =>
{
return View["index"];
};
}

这段代码就是Nancy的核心思想。Get["/"]是指:我要处理关于所有对于网站根目录的请求。比如说你的网站域名为example.com,那么"/"就代表example.com本身。"/login"就代表example.com/login。也就是说,路径永远是相对于网站根目录的。

那么Get是什么意思呢?你应该已经猜到了:这代表请求的verb,也就是"GET"。那么整段函数的意思就很明显了:对于所有访问网站根目录的GET请求,我们都返回一个index页面。这里的index对应你项目下的index.sshtml。

SSHTML
SSHTML是一种简单的视图引擎。如果你知道Razor(.cshtml),那么你可以把SSHTML相像成另一个版本的Razor,虽然它们二者的语法相去甚远。SSHTML我就不在这里介绍了,因为你可以在这里找到更好的文档。

静态页面 - Modules and Tests
为了热身,我们从静态页面开始。前面说过,我们将利用NancyModule进行开发。首先删掉你的IndexModule和IndexModuleTest。我们来想一下:
Sign in, Sign out -- 这组功能我们放在LoginModule中。
Sign-up -- 这一功能我们用AccountModule来实现。
Memo -- 核心功能,我们封装到MemoModule里。

因此,根据上面所讲的,建立三个NancyModule类,具体如下:

public class AccountModule : NancyModule
{
public AccountModule()
{
Get["/signup"] = parameters =>
{
return View["account/create.sshtml"];
};
}
}


        
public LoginModule()
{
Get["/login"] = parameters =>
{
return View["login/login.sshtml"];
};
}


        
public MemoModule()
{
Get["/"] = parameters =>
{
return View["memo/index"];
};
}


相应的,我们需要对应的测试类:
public class AccountTest : BaseTest
{
[Test]
public void signup_route_should_be_successful()
{
var browser = new Browser(Bootstrapper);
var response = browser.Get("/signup");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}

    public class LoginTest : BaseTest
{
[Test]
public void login_route_should_be_successful()
{
var browser = new Browser(Bootstrapper);
var response = browser.Get("/login");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}


    public class MemoTest : BaseTest
{
[Test]
public void root_route_should_be_successful()
{
var browser = new Browser(Bootstrapper);
var response = browser.Get("/");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}


你会发现以上三个类都继承了BaseTest:
    [TestFixture]
public abstract class BaseTest
{
private INancyBootstrapper _bootsrapper = new ConfigurableBootstrapper(with =>
{
with.Module<AccountModule>();
with.Module<LoginModule>();
with.Module<MemoModule>();
with.RootPathProvider(new TestRootPathProvider());
});

protected INancyBootstrapper Bootstrapper
{
get { return _bootsrapper; }
}
}

有了这些以后,如果你重新编译整个项目,然后用NUnit去跑测试,测试应该不会通过,原因在于我们还没有任何View,即视图。

静态页面 - 视图
如果你有一点项目经验,你就会知道,首先我们得有个模版页。在Views文件夹下,新建_master.sshtml,_footer.sshtml和_header.sshtml。

如果你是前端开发人员,你应该有用过前端框架的经验。恰好最近Bootstrap3发布了,我们就用Bootstrap3,这样可以节省很多编写和调试CSS的时间。

到这里下载Bootstrap: http://getbootstrap.com/getting-started/

Bootstrap需要jQuery的支持,所以你还得下个jQuery,我下载的是jQuery-1.10.2(如果你和我一样,一点也不想支持IE9以下的版本的浏览器,你也可以下载jQuery 2.0+,这是题外话了)。

一切下载都顺利的话,把bootstrap.css放到Contet/css下(如果你没有其中任何文件夹,直接新建一个就可以)。顺便新建一个non-responsive.css,其内容如下:


/* Template-specific stuff
*
* Customizations just for the template—these are not necessary for anything
* with disabling the responsiveness.
*/

/* Account for fixed navbar */
body {
padding-top: 70px;
padding-bottom: 30px;
}

/* Finesse the page header spacing */
.page-header {
margin-bottom: 30px;
}
.page-header .lead {
margin-bottom: 10px;
}


/* Non-responsive overrides
*
* Utilitze the following CSS to disable the responsive-ness of the container,
* grid system, and navbar.
*/

/* Reset the container */
.container {
max-width: none !important;
width: 970px;
}

/* Demonstrate the grids */
.col-xs-4 {
padding-top: 15px;
padding-bottom: 15px;
background-color: #eee;
border: 1px solid #ddd;
background-color: rgba(86,61,124,.15);
border: 1px solid rgba(86,61,124,.2);
}

.container .navbar-header,
.container .navbar-collapse {
margin-right: 0;
margin-left: 0;
}

/* Always float the navbar header */
.navbar-header {
float: left;
}

/* Undo the collapsing navbar */
.navbar-collapse {
display: block !important;
height: auto !important;
padding-bottom: 0;
overflow: visible !important;
}

.navbar-toggle {
display: none;
}

.navbar-brand {
margin-left: -15px;
}

/* Always apply the floated nav */
.navbar-nav {
float: left;
margin: 0;
}
.navbar-nav > li {
float: left;
}
.navbar-nav > li > a {
padding: 15px;
}

/* Redeclare since we override the float above */
.navbar-nav.navbar-right {
float: right;
}

/* Undo custom dropdowns */
.navbar .open .dropdown-menu {
position: absolute;
float: left;
background-color: #fff;
border: 1px solid #cccccc;
border: 1px solid rgba(0, 0, 0, 0.15);
border-width: 0 1px 1px;
border-radius: 0 0 4px 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
}
.navbar .open .dropdown-menu > li > a {
color: #333;
}
.navbar .open .dropdown-menu > li > a:hover,
.navbar .open .dropdown-menu > li > a:focus,
.navbar .open .dropdown-menu > .active > a,
.navbar .open .dropdown-menu > .active > a:hover,
.navbar .open .dropdown-menu > .active > a:focus {
color: #fff !important;
background-color: #428bca !important;
}
.navbar .open .dropdown-menu > .disabled > a,
.navbar .open .dropdown-menu > .disabled > a:hover,
.navbar .open .dropdown-menu > .disabled > a:focus {
color: #999 !important;
background-color: transparent !important;
}


non-responsive.css来自于Bootstrap的一个模版:http://getbootstrap.com/examples/non-responsive/

顺便说一下:我就不在这里做响应式页面了,虽然Bootstrap3倾向于于mobile-first的开发模式,但是这篇教程不是前段教程,所以我们就直接做成非响应式的。如果你对CSS感兴趣,那么我推荐CSS Missing Manual给你。如果你对写CSS非常感兴趣,你还需要学习SASS或LESS(链接我就不给了,自己google一下)。

Okay,下面我们来填充_master.sshtml:
<!DOCTYPE html>
<html>
<head>
<title>My Memo</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<!-- Bootstrap -->
<link href="@Path['~/Content/css/bootstrap.css']" rel="stylesheet" media="screen"/>
<link href="@Path['~/Content/css/non-responsive.css']" rel="stylesheet" media="screen"/>
<script src="@Path['~/Content/js/jquery-1.10.2.js']"></script>
<script src="@Path['~/Content/js/bootstrap.js']"></script>
</head>
<body>
<header>
@Partial['_header.sshtml']
</header>
@Section['content']
<footer>
@Partial['_footer.sshtml']
</footer>
</body>
</html>


紧接着是_header.sshtml:
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="@Path['~/']">My Memo</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="@Path['~/']">Memo</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="@Path['~/login']">Login</a></li>
<li><a href="@Path['~/signup']">Sign up</a></li>
</ul>
</div>
</div>
</div>


最后是_footer.sshtml,我们暂时将其留空。

在Views下新建三个文件夹:account, login, memo。
在account中添加create.sshtml:
@Master['_master.sshtml']

@Section['content']
<div class="container">

<div class="page-header">
<h1>Sign up</h1>
</div>

</div>
@EndSection

在login中添加login.sshtml:
@Master['_master.sshtml']

@Section['content']
<div class="container">

<div class="page-header">
<h1>Log in</h1>
</div>

</div>
@EndSection

在memo中添加index.sshtml:
@Master['_master.sshtml']

@Section['content']
<div class="container">

<div class="page-header">
<h1>Memo</h1>
<p class="lead">You have the following memos.</p>
</div>

</div>
@EndSection


有了这些文件之后,重新编译,然后用NUnit跑测试。如果跑不通,请大家根据错误信息自行调试。


总结一下,今天内容可能稍微有点多,我们主要学习了:
NancyModule,SSHTML(Super Simple View Engine),Bootstrap得配置。

待续。
...全文
11780 117 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
117 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzbz521 2014-03-13
  • 打赏
  • 举报
回复
新手一个,虽然看着还迷糊,还是赞一下楼主~
javatemptation 2013-10-24
  • 打赏
  • 举报
回复
楼主不继续写了么?
chagola 2013-09-17
  • 打赏
  • 举报
回复
比较复杂,学习中
xinqing1017 2013-09-17
  • 打赏
  • 举报
回复
看上去很不错的样子
瘦又美 2013-09-16
  • 打赏
  • 举报
回复
ly106476001 2013-09-16
  • 打赏
  • 举报
回复
谢谢分享!!!!。。
红白阿森纳 2013-09-16
  • 打赏
  • 举报
回复
学习了 谢谢
临沭远大制冷 2013-09-15
  • 打赏
  • 举报
回复
学习了 路过谢谢老师
u012122452 2013-09-14
  • 打赏
  • 举报
回复
顶楼主,楼主写的很有帮助
rrrvfp 2013-09-14
  • 打赏
  • 举报
回复
初来乍到,多多关照
尸香魔芋001 2013-09-14
  • 打赏
  • 举报
回复
赞一个。。。
黯月 2013-09-13
  • 打赏
  • 举报
回复
受教了
jamesking2008 2013-09-12
  • 打赏
  • 举报
回复
感谢分享,学到了很多 !
dadaobuyuanren 2013-09-12
  • 打赏
  • 举报
回复
学习一些基础知识,谢谢!!
瘦又美 2013-09-11
  • 打赏
  • 举报
回复
有用支持
火花一点点点 2013-09-10
  • 打赏
  • 举报
回复
很好啊,顶一个,学到了很多 !
到佛山供电局 2013-09-10
  • 打赏
  • 举报
回复
日月四季 2013-09-10
  • 打赏
  • 举报
回复
好东西。慢慢学习
narutocandy 2013-09-09
  • 打赏
  • 举报
回复
厉害厉害厉害啊~
d好水电费 2013-09-09
  • 打赏
  • 举报
回复
还是很复杂啊
加载更多回复(64)

62,241

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧