• Nancy之基于Nancy.Hosting.Aspnet的小Demo


    近来学习了一下Nancy这个框架,感觉挺好用的,就写篇简单的文章记录一下大致用法,由于是刚接触,写的代码

    可能不规范,也没有具体的分层。。莫吐槽。。。

    Nancy的官网:http://nancyfx.org/

    GitHub地址:https://github.com/NancyFx/Nancy

    Nancy在文档的介绍 -- 轻量级

    " Nancy is a lightweight, low-ceremony, framework for building HTTP based services on .NET and Mono. "

    Nancy有多种Hosting:

      Hosting Nancy with ASP.NET
      Hosting Nancy with WCF
      Hosting Nancy with Azure
      Hosting Nancy with OWIN
                Web (Katana)
                Self Hosting
                Environment Variables
                Conditional Pass-through
      Hosting Nancy with Umbraco
      Hosting Nancy with Nginx on Ubuntu
      Hosting Nancy with FastCgi
      Self Hosting Nancy
      Implementing a Host
      Accessing the client certificate when using SSL

    本文写的Demo是基于Hosting Nancy with ASP.NET。

    开发环境 :win 10 + VS2015 Community + SqlServer 2012

    废话不多说,开始正题:

    一、新建一个空的asp.net项目

    建好之后空空如也

    二、通过NuGet添加Nancy相关的Packages

        

    主要是Nancy、Nancy.Hosting.Aspnet、Nancy.Viewengines.Razor这三个。其版本依次为1.4.3、1.4.1、1.4.3

    我这里选择的视图引擎是Razor,习惯了,你们可以选择其他,这个问题不大。

    三、更新一下Razor

    默认安装Nancy.Viewengines.Razor之后,它会安装 Microsoft.AspNet.Razor.2.0.30506.0,我们用的是最新版的3.2.3

    在NuGet通过已安装的Packages来更新

    到这里,基本的工作已经OK了。

    这里用到了Dapper,所以我也添加了它的引用。

    注:这里是通过NuGet安装的,所以它也在web.config里生成了一些配置。如果是手动添加引用的,注意要修改web.config。

    四、加入css和javascript文件

    允许我偷偷懒,这里的我是直接copy一般新建mvc项目的,就连页面布局也是用的新建项目的模板。。

    五、新建Modules、Models、ViewModels、Views四个文件夹

    Modules-->相当于MVC中的Controllers文件夹

    Models-->存放模型

    ViewModels-->存放视图模型

    Views-->存放视图

    六、在Views下面建一个布局页_Layout.cshtml

    就新建的mvc模板copy过来,稍加修改

     1 @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>
     2 <!DOCTYPE html>
     3 <html>
     4 <head>
     5     <meta charset="utf-8" />
     6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     7     <title>@ViewBag.Title - Catcher's NancyDemo</title>
     8     <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
     9     <link href="~/Content/Site.css" rel="stylesheet" />    
    10     <link rel="shortcut icon" href="~/favicon.ico" />
    11 </head>
    12 <body>
    13     <div class="navbar navbar-inverse navbar-fixed-top">
    14         <div class="container">
    15             <div class="navbar-header">
    16                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
    17                     <span class="icon-bar"></span>
    18                     <span class="icon-bar"></span>
    19                     <span class="icon-bar"></span>
    20                 </button>
    21                 <a href="/" class="navbar-brand">NancyDemo</a>
    22             </div>
    23             <div class="navbar-collapse collapse">
    24                 <ul class="nav navbar-nav">
    25                     <li><a href="/">首页</a></li>
    26                     <li><a href="/home/about">关于我们</a></li>
    27                     <li><a href="/home/contact">联系我们</a></li>
    28                     <li><a href="/movie/">电影</a></li>
    29                     <li><a href="/movie-type/">类型</a></li>
    30                 </ul>
    31             </div>
    32         </div>
    33     </div>
    34     <div class="container body-content">
    35         @RenderBody()
    36         <hr />
    37         <footer>
    38             <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
    39         </footer>
    40     </div>
    41     <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    42     <script src="~/Scripts/bootstrap.min.js"></script>
    43 </body>
    44 </html>
    _Layout.cshtml

    七、在Modules下新建一个HomeModules.cs,具体如下:

     1 public class HomeModule : NancyModule
     2     {
     3         public HomeModule()
     4         {
     5             Get["/"] = _ => ShowHomePage();
     6             Get["/home/about"] = _ => ShowAboutPage();
     7             Get["/home/contact"] = _ => ShowContactPage();
     8         }
     9 
    10         private dynamic ShowContactPage()
    11         {
    12             return View["Contact"];
    13         }
    14 
    15         private dynamic ShowAboutPage()
    16         {
    17             return View["About"];
    18         }
    19 
    20         private dynamic ShowHomePage()
    21         {
    22             return View["Index"];
    23         }
    24     }
    HomeModule.cs

    同时在Views文件夹下面新建一个Home的子文件夹,在把mvc模板中的Index.cshtml,About.cshtml,Contact.cshtml

    copy过来稍加修改

     1 @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>
     2 @{
     3     ViewBag.Title = "首页";
     4     Layout = "Views/_Layout.cshtml";
     5 }
     6 <div class="jumbotron">
     7     <h1>NancyDemo</h1>
     8     <p class="lead">Nancy is a lightweight, low-ceremony, framework for building HTTP based services on .NET and Mono. The goal of the framework is to stay out of the way as much as possible and provide a super-duper-happy-path to all interactions.</p>
     9     <p><a href="http://nancyfx.org/" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
    10 </div>
    Index.cshtml
    1 @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>
    2 @{
    3     ViewBag.Title = "About";
    4     Layout = "Views/_Layout.cshtml";
    5 }
    6 <h2>@ViewBag.Title.</h2>
    7 <p>Use this area to provide additional information.</p>
    About.cshtml
     1 @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>
     2 @{
     3     ViewBag.Title = "Contact";
     4     Layout = "Views/_Layout.cshtml";
     5 }
     6 <h2>@ViewBag.Title.</h2>
     7 
     8 <address>
     9     One Microsoft Way<br />
    10     Redmond, WA 98052-6399<br />
    11     <abbr title="Phone">P:</abbr>
    12     425.555.0100
    13 </address>
    14 
    15 <address>
    16     <strong>Support:</strong>   <a href="mailto:Support@example.com">Support@example.com</a><br />
    17     <strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
    18 </address>
    Contact.cshtml

    然后F5,跑一下

         

    已经能跑起来了。

    下面就是结合数据库了。

    八、在MOdels下面建两个类

     1 public class Movie
     2     {
     3         public int MovieId { get; set; }
     4 
     5         public string MovieName { get; set; }
     6 
     7         public int MovieTypeId { get; set; }
     8 
     9         public DateTime MovieAddTime { get; set; }
    10 
    11         public virtual MovieType MovieType { get; set; }
    12 
    13         public Movie()
    14         {
    15             MovieAddTime = DateTime.Now;
    16         }
    17     }
    Movie.cs
     1     public class MovieType
     2     {
     3         public MovieType()
     4         {
     5             Movies = new HashSet<Movie>();
     6         }
     7 
     8 
     9         public int TypeId { get; set; }
    10 
    11         public string TypeName { get; set; }
    12 
    13         public virtual ICollection<Movie> Movies { get; set; }
    14     }
    MovieType.cs

    以Movie表为例,继续下面的工作。

    九、由于movie表中的数据展示,抽取出应该有的视图模型

    在ViewModels文件夹下面建立MovieViewModel.cs、MovieListViewModel.cs

     1     public class MovieViewModel
     2     {
     3         public int MovieId { get; set; }
     4 
     5         public string MovieName { get; set; }
     6 
     7         public int MovieTypeId { get; set; }
     8 
     9         public string MovieTypeName { get; set; }
    10 
    11         public DateTime MovieAddTime { get; set; }
    12     }
    MovieViewModel.cs
    1      public class MovieListViewModel
    2     {
    3         public IEnumerable<MovieViewModel> Movies { get; set; }
    4     }
    MovieListViewModel.cs

    十、现在就该写写烦人mvc控制器的东西了,在Modules文件夹下建立MovieModules.cs

    把数据提取出来

     1     public class MovieModule : NancyModule
     2     {
     3         public MovieModule() : base("/movie")
     4         {
     5             Get["/"] = _ => ShowMovieIndexPage();            
     6         }
     7 
     8         private readonly string _sqlconnection =
     9                 "Data Source=192.168.0.71;Initial Catalog=NancyDemo;User Id=sa;Password=dream_time1314;";
    10 
    11         public SqlConnection OpenConnection()
    12         {
    13             SqlConnection connection = new SqlConnection(_sqlconnection);
    14             connection.Open();
    15             return connection;
    16         }
    17      
    18         private dynamic ShowMovieIndexPage()
    19         {
    20             using (IDbConnection conn = OpenConnection())
    21             {
    22                 string getAllMoviesStoredProcedure = @"up_GetAllMovies";
    23                 MovieListViewModel viewModel = new MovieListViewModel
    24                 {
    25                     Movies = conn.Query<MovieViewModel>(getAllMoviesStoredProcedure,
    26                     null, null, true, null, CommandType.StoredProcedure)
    27                 };
    28                 return View["Index", viewModel];
    29             }
    30         }
    31     }
    MovieModule.cs

    然后就去编写视图

     在Views下面新建一个Movie文件夹,用于存放相关视图

     1 @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<MovieDemo.ViewModels.MovieListViewModel>
     2 @{
     3     Layout = "Views/_Layout.cshtml";
     4     ViewBag.Title = "电影列表";
     5 }
     6 <a href="/movie/create">添加</a>
     7 <div>
     8     <table class="table">
     9         <tr>
    10             <th>
    11                 #
    12             </th>
    13             <th>
    14                 电影名称
    15             </th>
    16             <th>
    17                 电影类型
    18             </th>
    19             <th>
    20                 添加时间
    21             </th>
    22             <th></th>
    23         </tr>
    24         @foreach (var item in Model.Movies)
    25             {
    26             <tr>
    27                 <td>
    28                     @item.MovieId
    29                 </td>
    30                 <td>
    31                     @item.MovieName
    32                 </td>
    33                 <td>
    34                     @item.MovieTypeName
    35                 </td>
    36                 <td>
    37                     @item.MovieAddTime
    38                 </td>
    39                 <td>
    40                     <a href="/movie/edit/@item.MovieId">修改</a>
    41                     <a class="delete" href="/movie/delete/@item.MovieId">删除</a>
    42                 </td>
    43             </tr>
    44         }
    45     </table>
    46 </div>
    Index.cshtml

    F5跑一下

    OK!

    然后就是修改某条数据,

    在MovieModule.cs 的构造函数中添加 

    1            Get["/edit/{movieId}"] = _ => ShowMovieEditPage(_.movieId);
    2             Post["/edit/{movieId}"] = _ =>
    3             {
    4                 var movie = this.Bind<Movie>();
    5                 return MovieEdit(movie);
    6             };

    然后添加ShowMovieEditPage和MovieEdit这两个方法

     1 private dynamic ShowMovieEditPage(int movieId)
     2         {
     3             string getOneMovieStoredProcedure = @"up_GetMovieByMovieId";
     4             string getALLTypeStoredProcedure = @"up_GetAllMovieTypes";
     5             DynamicParameters dynamicParameters = new DynamicParameters();
     6             dynamicParameters.Add("@MovieId", movieId);
     7 
     8             using (IDbConnection conn = OpenConnection())
     9             {
    10                 var movieViewModel = conn.Query<MovieViewModel>(getOneMovieStoredProcedure, dynamicParameters, null, true, null, CommandType.StoredProcedure).SingleOrDefault();
    11                 ViewBag.typeList = conn.Query<MovieType>(getALLTypeStoredProcedure, null, null, true, null, CommandType.StoredProcedure);
    12                 return View["Edit", movieViewModel];
    13                 
    14             }
    15         }
    ShowMovieEditPage
     1     private dynamic MovieEdit(Movie movie)
     2         {
     3             string updateMovieStoredProcedure = @"up_UpdateMovieByMovieId";
     4             DynamicParameters dynamicParameters = new DynamicParameters();
     5             dynamicParameters.Add("@MovieId", movie.MovieId);
     6             dynamicParameters.Add("@MovieName", movie.MovieName);
     7             dynamicParameters.Add("@MovieTypeId", movie.MovieTypeId);
     8 
     9             using (IDbConnection conn = OpenConnection())
    10             {
    11                 conn.Execute(updateMovieStoredProcedure, dynamicParameters, null, null, CommandType.StoredProcedure);
    12                 return Response.AsRedirect("/movie");
    13             }
    14         }
    MovieEdit

    添加一个Movie的Edit视图

     1 @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<MovieDemo.ViewModels.MovieViewModel>
     2 @{
     3     ViewBag.Title = "修改电影信息";
     4     Layout = "Views/_Layout.cshtml";
     5 }
     6 
     7 <form action="/movie/edit/@Model.MovieId" method="post">
     8     <div class="form-group">
     9         <label class="control-label col-md-2">电影名称</label>
    10         <div class="col-md-10">
    11             <input type="text" class="form-control" id="MovieName" name="MovieName" value="@Model.MovieName" />
    12         </div>
    13     </div>
    14     <div class="form-group">
    15         <label class="control-label col-md-2">电影类型</label>
    16         <div class="col-md-10">
    17             <select id="MovieTypeId" name="MovieTypeId" class="form-control">
    18                 @foreach (var item in (System.Collections.Generic.List<MovieDemo.Models.MovieType>)ViewBag.typeList)
    19                 {
    20                     if (Model.MovieTypeId == item.TypeId)
    21                     {
    22                         <option selected="selected" value="@item.TypeId">@item.TypeName</option>
    23                     }
    24                     else
    25                     {
    26                         <option value="@item.TypeId">@item.TypeName</option>
    27                     }
    28                 }
    29 
    30             </select>
    31         </div>
    32     </div>
    33     <div class="form-group">
    34         <div class="col-md-offset-2 col-md-10">
    35             <input type="submit" value="修改" class="btn btn-default" />
    36         </div>
    37     </div>
    38 </form>
    Edit.cshtml

    然后即可跑起来了。

    其中用到了一个模型绑定,需要添加Nancy.ModelBinding引用,有了这个绑定,省了很多事!!

     var movie = this.Bind<Movie>();

    同理,增加和删除也是同样的做法,下面是MovieModule.cs的完整代码

      1 using MovieDemo.Models;
      2 using MovieDemo.ViewModels;
      3 using Dapper;
      4 using Nancy;
      5 using Nancy.ModelBinding;
      6 using System.Data;
      7 using System.Data.SqlClient;
      8 using System.Linq;
      9 
     10 namespace MovieDemo.Modules
     11 {
     12     public class MovieModule : NancyModule
     13     {
     14         public MovieModule() : base("/movie")
     15         {
     16             Get["/"] = _ => ShowMovieIndexPage();
     17 
     18             Get["/edit/{movieId}"] = _ => ShowMovieEditPage(_.movieId);
     19             Post["/edit/{movieId}"] = _ =>
     20             {
     21                 var movie = this.Bind<Movie>();
     22                 return MovieEdit(movie);
     23             };
     24 
     25             Get["/create"] = _ => ShowMovieCreatePage();
     26             Post["/create"] = _ =>
     27             {
     28                 var movie = this.Bind<Movie>();
     29                 return MovieCreate(movie);
     30             };
     31 
     32             Get["/delete/{movieId}"] = _ => MovieDelete(_.movieId);
     33         }
     34 
     35         private readonly string _sqlconnection =
     36                 "Data Source=192.168.0.71;Initial Catalog=NancyDemo;User Id=sa;Password=dream_time1314;";
     37 
     38         public SqlConnection OpenConnection()
     39         {
     40             SqlConnection connection = new SqlConnection(_sqlconnection);
     41             connection.Open();
     42             return connection;
     43         }
     44 
     45         private dynamic MovieDelete(int movieId)
     46         {
     47             string deleteMovieStoredProcedure = @"up_DeleteMovieByMovieId";
     48             DynamicParameters dynamicParameters = new DynamicParameters();
     49             dynamicParameters.Add("@MovieId", movieId);
     50             using (IDbConnection conn = OpenConnection())
     51             {
     52                 conn.Execute(deleteMovieStoredProcedure, dynamicParameters, null, null, CommandType.StoredProcedure);
     53                 return Response.AsRedirect("/movie");
     54             }
     55         }
     56 
     57         private dynamic MovieCreate(Movie movie)
     58         {
     59             string createMovieStoredProcedure = @"up_InsertMovie";
     60             DynamicParameters dynamicParameters = new DynamicParameters();
     61             dynamicParameters.Add("@MovieName", movie.MovieName);
     62             dynamicParameters.Add("@MovieTypeId", movie.MovieTypeId);
     63             dynamicParameters.Add("@MovieAddTime", movie.MovieAddTime);
     64 
     65             using (IDbConnection conn = OpenConnection())
     66             {
     67                 conn.Execute(createMovieStoredProcedure, dynamicParameters, null, null, CommandType.StoredProcedure);
     68                 return Response.AsRedirect("/movie");
     69             }
     70         }
     71 
     72         private dynamic ShowMovieCreatePage()
     73         {
     74             string getALLTypeStoredProcedure = @"up_GetAllMovieTypes";
     75             using (IDbConnection conn = OpenConnection())
     76             {
     77                 MovieTypeListViewModel viewModel = new MovieTypeListViewModel
     78                 {
     79                     MovieTypes = conn.Query<MovieType>(getALLTypeStoredProcedure, null, null, true, null, CommandType.StoredProcedure)
     80                 };
     81                 return View["Create", viewModel];
     82             }
     83         }
     84 
     85         private dynamic MovieEdit(Movie movie)
     86         {
     87             string updateMovieStoredProcedure = @"up_UpdateMovieByMovieId";
     88             DynamicParameters dynamicParameters = new DynamicParameters();
     89             dynamicParameters.Add("@MovieId", movie.MovieId);
     90             dynamicParameters.Add("@MovieName", movie.MovieName);
     91             dynamicParameters.Add("@MovieTypeId", movie.MovieTypeId);
     92 
     93             using (IDbConnection conn = OpenConnection())
     94             {
     95                 conn.Execute(updateMovieStoredProcedure, dynamicParameters, null, null, CommandType.StoredProcedure);
     96                 return Response.AsRedirect("/movie");
     97             }
     98         }
     99 
    100         private dynamic ShowMovieEditPage(int movieId)
    101         {
    102             string getOneMovieStoredProcedure = @"up_GetMovieByMovieId";
    103             string getALLTypeStoredProcedure = @"up_GetAllMovieTypes";
    104             DynamicParameters dynamicParameters = new DynamicParameters();
    105             dynamicParameters.Add("@MovieId", movieId);
    106 
    107             using (IDbConnection conn = OpenConnection())
    108             {
    109                 var movieViewModel = conn.Query<MovieViewModel>(getOneMovieStoredProcedure, dynamicParameters, null, true, null, CommandType.StoredProcedure).SingleOrDefault();
    110                 ViewBag.typeList = conn.Query<MovieType>(getALLTypeStoredProcedure, null, null, true, null, CommandType.StoredProcedure);
    111                 return View["Edit", movieViewModel];
    112                 
    113             }
    114         }
    115 
    116         private dynamic ShowMovieIndexPage()
    117         {
    118             using (IDbConnection conn = OpenConnection())
    119             {
    120                 string getAllMoviesStoredProcedure = @"up_GetAllMovies";
    121                 MovieListViewModel viewModel = new MovieListViewModel
    122                 {
    123                     Movies = conn.Query<MovieViewModel>(getAllMoviesStoredProcedure,
    124                     null, null, true, null, CommandType.StoredProcedure)
    125                 };
    126                 return View["Index", viewModel];
    127             }
    128         }
    129     }
    130 }
    MovieModule.cs

     在添加相应的视图即可完成。

    十一、下面还需要简单讲一下Bootstrapper

    这个东西可以简单认为是引导程序,你可以自定义一些鬼东西,把它当作一个容器来用,

    还可以通过它来实现依赖注入,里面有个默认的 TinyIoC 。。。。。详细介绍请看https://github.com/NancyFx/Nancy/wiki/Bootstrapper

    下面是我的CustomBootstrapper.cs配置

     1 public class CustomBootstrapper : DefaultNancyBootstrapper
     2     {
     3         protected override void ConfigureApplicationContainer(TinyIoCContainer container)
     4         {
     5             base.ConfigureApplicationContainer(container);
     6             //container.Register<IMoviesRepository, MoviesRepository>();
     7             //container.Register<IMovieTypesRepository, MovieTypesRepository>();        
     8         }
     9         protected override void ConfigureConventions(NancyConventions nancyConventions)
    10         {
    11             base.ConfigureConventions(nancyConventions);
    12             nancyConventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("Scripts"));
    13             nancyConventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("Content"));
    14         }
    15     }
    CustomBootstrapper.cs

    依赖注入我是没有用的,所以我注释了。用过Ninject、Autofac、Unity这些的,相信依赖注入这一块理解起来So easy!

    Nancy也有相应的拓展

    https://github.com/NancyFx/Nancy.Bootstrappers.Autofac

    https://github.com/NancyFx/Nancy.Bootstrappers.Unity

    https://github.com/NancyFx/Nancy.Bootstrappers.Ninject

    还有一块是ConfigureConventions

    这一块似乎是用来处理静态文件(css、js)的,跟Mvc中的BundleConfig很类似

    到这里,开发工作已经完成。下面是部署的时候了。

    十二、将做的MovieDemo部署到Linux下

    Linux环境及配置

    CentOS 6.7  + mono 4.2.2 + Jexus 5.8.0

    将发布过后的目录上传到centos的 /var/www/ 中,然后在 /usr/jexus/siteconf 中建立一个新的配置文件

    重新启动jexus即可。

    下面上几张运行的图

    完全的无缝兼容。

    本篇的完整代码已托管到GitHub

     下载地址:https://github.com/hwqdt/Demos/tree/master/NancyDemoWithHostingAspnet

    下雨天,心情压抑,写篇bolg来拯救自己的好心情 ~_~

    后面有时间会写基于owin的demo

  • 相关阅读:
    创业4
    创业3
    PowerBI开发 第十四篇:使用M公式添加列
    PowerBI开发 第十三篇:增量刷新
    PowerBI开发 第十二篇:钻取
    SSIS 连接数据
    SSIS 调试和故障排除
    SQL Server 日志和代理的错误日志
    SSIS 检查点(CheckPoint)内幕
    SSIS 如何处理逻辑类型的转换?
  • 原文地址:https://www.cnblogs.com/catcher1994/p/5145173.html
Copyright © 2020-2023  润新知