Nancy之基于Nancy.Hosting.Aspnet的小Demo
原文: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

posted on 2018-05-21 16:54 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/9068073.html

Nancy之基于Nancy.Hosting.Aspnet的小Demo相关推荐

  1. Nancy之基于Self Hosting的补充小Demo

    原文:Nancy之基于Self Hosting的补充小Demo 前面把Hosting Nancy with ASP.NET.Self Hosting Nancy和Hosting Nancy with ...

  2. nancy 显示html网页,Nancy之基于Nancy.Hosting.Self的小Demo_html/css_WEB-ITnose

    今天来做个基于Nancy.Hosting.Self的小Demo. 关于Self Hosting Nancy,官方文档的介绍如下 https://github.com/NancyFx/Nancy/wik ...

  3. Nancy之基于Nancy.Owin的小Demo

    前面做了基于Nancy.Hosting.Aspnet和Nancy.Hosting.Self的小Demo 今天我们来做个基于Nancy.Owin的小Demo 开始之前我们来说说什么是Owin和Katan ...

  4. vue.js反编译_基于electron-vue开发的微信小程序反编译客户端

    开源一个小程序反编译客户端 咨询小程序反编译的同学比较多,虽然有开源库但是还是有同学不清楚如何去操作,所以索性做了一个客户端方便进行小程序的反编译 # 技术选型 网上已经有大佬实现了C#版的反编译工具 ...

  5. python点名代码_基于python tkinter的点名小程序功能的实例代码

    基于python tkinter的点名小程序功能的实例代码,花名册,次数,窗口,未找到,初始化 基于python tkinter的点名小程序功能的实例代码 易采站长站,站长之家为您整理了基于pytho ...

  6. 基于改进SSD的车辆小目标检测方法

    基于改进SSD的车辆小目标检测方法 人工智能技术与咨询 来源:<应用光学>,作者李小宁等 摘 要:地面车辆目标检测问题中由于目标尺寸较小,目标外观信息较少,且易受背景干扰等的原因,较难精确 ...

  7. python登录界面源码_基于Python的自媒体小助手---登录页面的实现代码

    核心技术:Python3.7 GUI技术:Tkinter (Python已经内置) 好多文章写Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 我看了N遍也没够好多东西都没有就基 ...

  8. 基于JQuery做的一个简单的点击显示和隐藏的小Demo

    最近新加入了一个公司,并接手到了一个新项目,是基于 Spring + Spring MVC + MyBatis 架构来搭建的,在公司领导的需求下修改功能,需要修改些修改些前端页面,原本很简单的就是一个 ...

  9. 基于云开发的微信小程序:个人相册ByUestcXiye

    基于云开发的微信小程序:个人相册ByUestcXiye 作业要求 第一次作业 第二次作业 结课作业 小程序开发入门 开发前的准备 注册微信小程序 新建一个模板小程序 开通云开发服务 第一次作业 参考资 ...

最新文章

  1. 不带头节点的链表有哪些缺点_23张图!万字详解「链表」,从小白到大佬!
  2. oracle 基础1
  3. 阿里GTS解密--GTS的原理、架构与特点
  4. 硅谷与人工智能的一段风流暧昧史
  5. 技术实践 | 网易云信视频转码提速之分片转码
  6. python怎么输出一个数组_python中实现将多个print输出合成一个数组
  7. 用户权限sudo、suid、sgid以及facl等
  8. python_线程读写操作一
  9. python 爬取豆瓣top100电影页面
  10. 静态代码块 构造代码块 构造方法的执行顺序
  11. Python-----包和日志的使用
  12. (转)使用C#开发ActiveX控件
  13. 2021-1-28Linux学习纪要
  14. 完美解决 fatal: unable to access ‘https://github.com/.../.git‘: Could not resolve host: github.com
  15. matlab切片操作
  16. 计算机专业必须考过英语4级吗,计算机专业英语必须过六级吗
  17. MATLAB制作歌曲
  18. ccfcsp-20190301小中大-JAVA语言
  19. 买了腾讯云服务器怎么ping,腾讯云服务器如何禁止Ping的功能
  20. Google Dremel 原理 – 如何能 3 秒分析 1PB

热门文章

  1. 云原生Spark UI Service在腾讯云云原生数据湖产品DLC的实践
  2. python小技巧:使用HTMLTestReport模板生成html报告
  3. Java中线程之间的通信方式
  4. 计算机考研计划论文,计算机研究生复试
  5. SQL 是最值得投资的语言,清华博士如是说!
  6. html表单提交前检查,form的onsubmit事件--表单提交前的验证最佳实现方式
  7. Sun Solaris 用户手册
  8. 一步步带你实现一个简单的express服务器,能让vue通过axios请求将图片上传到阿里云OSS
  9. mac修改vmware flusion网络适配器的nat配置
  10. Prometheus Grafana 搭建监控系统