Asp.net Core基于MVC框架实现PostgreSQL操作

简单介绍

Asp.net Core最大的价值在于跨平台、跨平台、跨平台。重要的事情说三遍。但是目前毕竟是在开发初期,虽然推出了1.0.0 正式版,但是其实好多功能还没有完善。比方说编译时的一些文件编码问题,辅助工具Tools的一些Bug,还有一些好用的模板和平台实现尚未完成等一些问题。但这毕竟是一个好的开始,并且在Github上,大家都还在积极的完善,你也可以参与进来。地址:https://github.com/aspnet

Asp.net Core在学习的时候,首先你应该跟着微软官方的入门教材来学习,在这里: https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html。这个入门教材很浅显易懂的让你了解了Asp.net Core mvc框架以及entity framework core的用法。不过缺点是,使用的是Sql compact数据库,也就是SQL Server数据库。要知道,我们使用Asp.net 的主要目的是实现跨平台部署,所以数据库的选择上,首选肯定不是SqlServer,否则意义何在?当然,目前Entity Framework core暂时还不支持所有数据库。截止2016年7月,支持情况如下:

Database Providers

The following providers are available

所以提供给我们选择的数据库还是有限的(主要是不支持MySql,Devart这东西笔者不了解,不评论)。总得来说,对MS SQL Server的支持肯定是最好的,所以场景允许下,首选Sql server。其次,就DB2和PostgreSQL可选了。笔者不喜欢DB2(很多原因,主要是开发操作管理麻烦,并非说DB2本身存在问题),PostgreSQL其实也不太好用,不过谁叫他免费呢,肯定是好多国内公司首选。

PostgreSQL本身历史悠久,记得好像上世纪80年代就存在了,免费开源,而且是有专门社区维护。设计理念是以健壮性为首选,所以收到光打企业级平台欢迎。关于PostgreSQL和MySQL之间的优缺点,这个其实不太好说,MySQL在损失健壮性的同时,提高了性能,并且支持很多非标准新特性,而PostgreSQL在健壮性上,号称不弱于Oracle,性能优秀,完全支持SQL标准,所以其实并不差。

准备环境

Ubuntu Server(16.04)虚拟机1台,IP:192.168.1.6 预装了PostgreSQL数据库,并配置好防火墙,ssh连接等基础环境。确保能够外部访问。

VS2015 Update3

Putty 和SSH Secure File Transfer Client

服务器环境部署

????参考之前的博客:http://blog.csdn.net/lanwilliam/article/details/51880124

开始

  1. 新建项目,选择Asp.net Core Web Application项目模板。

  2. 选择Web应用程序模板,然后修改身份验证哪里,选择不进行身份验证。

    这里要说一下,Asp.net core项目中,包含一个Identity子项目,在GitHub上有介绍如下:

    这里大家一看就知道了,这就是原来提供的ASP.net自带的权限框架。这个框架现在其实非常强大了,还支持Google和TWriter等OAuth用法,不过缺点是只支持SQL Server数据库。如果选择了个人用户账户,那么会默认使用这个框架创建项目。我们希望用PostgreSQL,所以不能选他,很遗憾。而且目前创建控制器等一些内置模板用法,都是基于SqlServer,用到这个Identity,大家如果看过微软的GettingStarted,就会看到介绍,所以建议大家首先学习微软GettingStarted。

    当然,不要勾选云中托管。

  3. 空白项目结构

    上图是新建完成的空白项目结构,你会发现Models,Data等文件夹都不存在,这里需要手动新建,并且丢进去一个class。

    必须要丢进去个class文件,让类定义的时候声明出Models和Data的命名空间,否则待会生成models文件的时候会报错。

  4. 增加项目引用

    Asp.net core项目有两种方法增加引用,一种是直接修改project.json,另一种是nuget。

    上述方法打开控制台

    输入如下命令

    会发现最后的Tools安装不了,可能nuget没同步过来,可以在project.json中手动添加。

    最后的文件如下:

    主要是圈选中的部分。可以看到这里我们用来操作PostgreSQL的Provider是Npgsql,这是aspnet下的一个子项目。可以在github找到。

    其他EntityFrameworkCore的引用,是从示例项目中搬来的。

  5. 生成Models文件

    这里要说明一下,微软MVC教程中时使用的模板创建的Controller,他会自动创建ApplicationDBContext和对应的Views视图文件,以及一些其他的内容。因为他更新了ApplicationDBContext文件和ApplicationDbContextModelSnapshot文件,所以控制台执行dotnet ef命令才会正常完成,这里无法用到这些方法。因为没选"个人用户账户",这里请自行尝试。

    dotnet ef migrations add Initial

    dotnet ef database update

    由于自行写DBContext类实现太麻烦,我们这里采取开发中常用的办法,首先设计数据库,然后根据数据库生成类。

    在数据库新建表如下:(测试用,看看就好)

    然后回到VS2015,在Nuget程序包控制台输入:

    Scaffold-DbContext "Server=192.168.1.6;Database=testdb;User ID=test;Password=test;" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Models

这个命令不用解释了吧?数据库连接,使用的数据库provider和输出目录。

顺利完成的话,Models下会出现几个类文件。

如果报错的话,请根据错误提示进行处理。处理原则,首先保证程序能够编译通过,然后确保Models下面没有存在本次要生成的同名文件,然后确认目前系统没有其他DBContext存在。现在dotnet core的好多工具都在完善中,健壮性都有待提高。

打开看看生成的文件:


using System;

using Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore.Metadata;

?

namespace PostgresSqlDemo.Models

{

public
partial
class
testdbContext : DbContext

{

protected
override
void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

{

#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.

optionsBuilder.UseNpgsql(@"Server=192.168.1.6;Database=testdb;User ID=test;Password=test;");

}

?

protected
override
void OnModelCreating(ModelBuilder modelBuilder)

{

modelBuilder.Entity<Blog>(entity =>

{

entity.ToTable("blog");

?

entity.Property(e => e.Id)

.HasColumnName("id")

.ValueGeneratedNever();

?

entity.Property(e => e.Title)

.IsRequired()

.HasColumnName("title")

.HasColumnType("varchar")

.HasMaxLength(300);

?

entity.Property(e => e.Url)

.IsRequired()

.HasColumnName("url")

.HasColumnType("varchar")

.HasMaxLength(300);

});

?

modelBuilder.Entity<TbUser>(entity =>

{

entity.HasKey(e => e.Userid)

.HasName("PK_tb_user");

?

entity.ToTable("tb_user");

?

entity.Property(e => e.Userid)

.HasColumnName("userid")

.ValueGeneratedNever();

?

entity.Property(e => e.Age).HasColumnName("age");

?

entity.Property(e => e.Name)

.IsRequired()

.HasColumnName("name")

.HasColumnType("varchar")

.HasMaxLength(30);

});

}

?

public
virtual
DbSet<Blog> Blog { get; set; }

public
virtual
DbSet<TbUser> TbUser { get; set; }

}

}

Entityframework中,默认是一个数据库使用唯一一个DBContext类进行管理。

  1. 修改DBContext文件

    模板已经提示给你,需要修改这部分代码,实现动态配置连接的目的。

    进行如下修改:

    注释掉OnConfiguring方法,增加构造函数,我们把注册放到Startup中去完成。

  2. 添加数据库连接配置项

    打开appsetting.json文件,增加如下配置:

    其实这就相当于原来asp.net中的Web.config中的ConnectionStrings。

  3. 注册DBContext

    打开StartUP.cs 文件,找到ConfigureServices方法,添加选中代码:

????????到这里就看明白了吧,注册DBContext,使用Npgsql,并给出数据库连接字符串。

  1. 增加控制器Controller

    在Controller文件夹下新建Controller文件,并添加如下代码:

    using Microsoft.AspNetCore.Mvc;

    using PostgresSqlDemo.Data;

    using PostgresSqlDemo.Models;

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Threading.Tasks;

    using Microsoft.EntityFrameworkCore;

    ?

    namespace PostgresSqlDemo.Controllers

    {

    public
    class
    TbUserController : Controller

    {

    private
    readonly
    testdbContext _context;

    ?

    public TbUserController(testdbContext context)

    {

    _context = context;

    }

    ?

    // GET: tbusers

    public
    async
    Task<IActionResult> Index()

    {

    return View(await _context.TbUser.ToListAsync());

    }

    ?

    public
    async
    Task<IActionResult> Details(Guid? id)

    {

    if (id == null)

    {

    return NotFound();

    }

    ?

    var tbuser = await _context.TbUser.SingleOrDefaultAsync(m => m.Userid == id);

    if (tbuser == null)

    {

    return NotFound();

    }

    ?

    return View(tbuser);

    }

    ?

    // GET: tbusers/Create

    public
    IActionResult Create()

    {

    return View();

    }

    ?

    // POST: tbusers/Create

    // To protect from overposting attacks, please enable the specific properties you want to bind to, for

    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.

    [HttpPost]

    [ValidateAntiForgeryToken]

    public
    async
    Task<IActionResult> Create([Bind("Userid,Name,Age")] TbUser tbuser)

    {

    if (ModelState.IsValid)

    {

    tbuser.Userid = Guid.NewGuid();

    _context.Add(tbuser);

    await _context.SaveChangesAsync();

    return RedirectToAction("Index");

    }

    return View(tbuser);

    }

    ?

    // GET: tbusers/Edit/5

    public
    async
    Task<IActionResult> Edit(Guid? id)

    {

    if (id == null)

    {

    return NotFound();

    }

    ?

    var tbuser = await _context.TbUser.SingleOrDefaultAsync(m => m.Userid == id);

    if (tbuser == null)

    {

    return NotFound();

    }

    return View(tbuser);

    }

    ?

    // POST: tbusers/Edit/5

    // To protect from overposting attacks, please enable the specific properties you want to bind to, for

    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.

    [HttpPost]

    [ValidateAntiForgeryToken]

    public
    async
    Task<IActionResult> Edit(Guid id, [Bind("Userid,Name,Age")] TbUser tbuser)

    {

    if (id != tbuser.Userid)

    {

    return NotFound();

    }

    ?

    if (ModelState.IsValid)

    {

    try

    {

    _context.Update(tbuser);

    await _context.SaveChangesAsync();

    }

    catch (DbUpdateConcurrencyException)

    {

    if (!tbuserExists(tbuser.Userid))

    {

    return NotFound();

    }

    else

    {

    throw;

    }

    }

    return RedirectToAction("Index");

    }

    return View(tbuser);

    }

    ?

    // GET: tbusers/Delete/5

    public
    async
    Task<IActionResult> Delete(Guid? id)

    {

    if (id == null)

    {

    return NotFound();

    }

    ?

    var tbuser = await _context.TbUser.SingleOrDefaultAsync(m => m.Userid == id);

    if (tbuser == null)

    {

    return NotFound();

    }

    ?

    return View(tbuser);

    }

    ?

    // POST: tbusers/Delete/5

    [HttpPost, ActionName("Delete")]

    [ValidateAntiForgeryToken]

    public
    async
    Task<IActionResult> DeleteConfirmed(Guid id)

    {

    var tbuser = await _context.TbUser.SingleOrDefaultAsync(m => m.Userid == id);

    _context.TbUser.Remove(tbuser);

    await _context.SaveChangesAsync();

    return RedirectToAction("Index");

    }

    ?

    private
    bool tbuserExists(Guid id)

    {

    return _context.TbUser.Any(e => e.Userid == id);

    }

    }

    }

    如果你看过Getting Started Asp.net core MVC的话,相信应该能够看懂,基本是把使用新增Controller模板生成的方法修改了一下拿过来用了。

    Asp.net core mvc中,默认路由名成为(name)Controller,所以我们这里叫TbUserController,访问的时候是http://youip/TbUser这样。并且默认是触发Index方法。

    Controller中,每个方法,都相当于一个客户端Form的Action。没有特殊声明的方法,默认为HttpGet,可以直接请求。需要Post数据的,请手动增加[HttpPost]声明。

    Async是C# 5.0后提供的关键字,是自动实现一个异步的方法,需要配合await关键字使用。Await会被自动转换为一个async的异步请求,后面的代码,会被自动放到completed方法中执行。这样处理能够极大的提高服务器的并发性能,具体请自行学习。

  2. 增加Views页面

    增加对应的页面如下:

Index.cshtml

@model IEnumerable<PostgresSqlDemo.Models.TbUser>

?

@{

ViewData["Title"] = "Index";

}

?

<h2>Index</h2>

?

<p>

<a
asp-action="Create">Create New</a>

</p>

<table
class="table">

<thead>

<tr>

<th>

@Html.DisplayNameFor(model => model.Userid)

</th>

<th>

@Html.DisplayNameFor(model => model.Name)

</th>

<th>

@Html.DisplayNameFor(model => model.Age)

</th>

?

<th></th>

</tr>

</thead>

<tbody>

@foreach (var item in Model)

{

<tr>

<td>

@Html.DisplayFor(modelItem => item.Userid)

</td>

<td>

@Html.DisplayFor(modelItem => item.Name)

</td>

<td>

@Html.DisplayFor(modelItem => item.Age)

</td>

?

<td>

<a
asp-action="Edit"
asp-route-id="@item.Userid">Edit</a> |

<a
asp-action="Details"
asp-route-id="@item.Userid">Details</a> |

<a
asp-action="Delete"
asp-route-id="@item.Userid">Delete</a>

</td>

</tr>

}

</tbody>

</table>

?

Create.cshtml

@model PostgresSqlDemo.Models.TbUser

?

@{

ViewData["Title"] = "Create";

}

?

<h2>Create</h2>

?

<form
asp-action="Create">

<div
class="form-horizontal">

<h4>TbUser</h4>

<hr
/>

<div
asp-validation-summary="ModelOnly"
class="text-danger"></div>

<div
class="form-group">

<label
asp-for="Name"
class="col-md-2 control-label"></label>

<div
class="col-md-10">

<input
asp-for="Name"
class="form-control"
/>

<span
asp-validation-for="Name"
class="text-danger"
/>

</div>

</div>

<div
class="form-group">

<label
asp-for="Age"
class="col-md-2 control-label"></label>

<div
class="col-md-10">

<input
asp-for="Age"
class="form-control"
/>

<span
asp-validation-for="Age"
class="text-danger"
/>

</div>

</div>

<div
class="form-group">

<div
class="col-md-offset-2 col-md-10">

<input
type="submit"
value="Create"
class="btn btn-default"
/>

</div>

</div>

</div>

</form>

?

<div>

<a
asp-action="Index">Back to List</a>

</div>

?

@section Scripts {

@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

}

?

Delete.cshtml

@model PostgresSqlDemo.Models.TbUser

?

@{

ViewData["Title"] = "Delete";

}

?

<h2>Delete</h2>

?

<h3>Are you sure you want to delete this?</h3>

<div>

<h4>Blog</h4>

<hr
/>

<dl
class="dl-horizontal">

<dt>

@Html.DisplayNameFor(model => model.Userid)

</dt>

<dd>

@Html.DisplayFor(model => model.Userid)

</dd>

<dt>

@Html.DisplayNameFor(model => model.Name)

</dt>

<dd>

@Html.DisplayFor(model => model.Name)

</dd>

<dt>

@Html.DisplayNameFor(model => model.Age)

</dt>

<dd>

@Html.DisplayFor(model => model.Age)

</dd>

</dl>

?

<form
asp-action="Delete">

<div
class="form-actions no-color">

<input
type="submit"
value="Delete"
class="btn btn-default"
/> |

<a
asp-action="Index">Back to List</a>

</div>

</form>

</div>

?

Details.cshtml

@model PostgresSqlDemo.Models.TbUser

?

@{

ViewData["Title"] = "Details";

}

?

<h2>Details</h2>

?

<div>

<h4>Blog</h4>

<hr
/>

<dl
class="dl-horizontal">

<dt>

@Html.DisplayNameFor(model => model.Userid)

</dt>

<dd>

@Html.DisplayFor(model => model.Userid)

</dd>

<dt>

@Html.DisplayNameFor(model => model.Name)

</dt>

<dd>

@Html.DisplayFor(model => model.Name)

</dd>

<dt>

@Html.DisplayNameFor(model => model.Age)

</dt>

<dd>

@Html.DisplayFor(model => model.Age)

</dd>

</dl>

</div>

<div>

<a
asp-action="Edit"
asp-route-id="@Model.Userid">Edit</a> |

<a
asp-action="Index">Back to List</a>

</div>

?

Edit.cshtml

@model PostgresSqlDemo.Models.TbUser

?

@{

ViewData["Title"] = "Edit";

}

?

<h2>Edit</h2>

?

<form
asp-action="Edit">

<div
class="form-horizontal">

<h4>Blog</h4>

<hr
/>

<div
asp-validation-summary="ModelOnly"
class="text-danger"></div>

<input
type="hidden"
asp-for="Userid"
/>

<div
class="form-group">

<label
asp-for="Name"
class="col-md-2 control-label"></label>

<div
class="col-md-10">

<input
asp-for="Name"
class="form-control"
/>

<span
asp-validation-for="Name"
class="text-danger"
/>

</div>

</div>

<div
class="form-group">

<label
asp-for="Age"
class="col-md-2 control-label"></label>

<div
class="col-md-10">

<input
asp-for="Age"
class="form-control"
/>

<span
asp-validation-for="Age"
class="text-danger"
/>

</div>

</div>

<div
class="form-group">

<div
class="col-md-offset-2 col-md-10">

<input
type="submit"
value="Save"
class="btn btn-default"
/>

</div>

</div>

</div>

</form>

?

<div>

<a
asp-action="Index">Back to List</a>

</div>

?

@section Scripts {

@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

}

?

  1. 增加验证脚本引用View文件

    <environment
    names="Development">

    <script
    src="~/lib/jquery-validation/dist/jquery.validate.js"></script>

    <script
    src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>

    </environment>

    <environment
    names="Staging,Production">

    <script
    src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"

    asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"

    asp-fallback-test="window.jQuery && window.jQuery.validator">

    </script>

    <script
    src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"

    asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"

    asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive">

    </script>

    </environment>

?

  1. 修改Layout.cshtml文件

    增加如上两个连接。Blog的添加参考TbUser。这里主要是想让大家看出来DBContext的用法,所以特意弄了两个实体类。

  2. 然后vs里面可以运行了,效果如下:

    这里没有改默认的页面。

    再看我们加的页面。

    并且asp.net mvc默认使用了bootstrap,所以我们可以用chrome的手机模式看看。



  3. 改成中文显示

    改一下TbUser.cs

    using System;

    using System.Collections.Generic;

    using System.ComponentModel.DataAnnotations;

    ?

    namespace PostgresSqlDemo.Models

    {

    public
    partial
    class
    TbUser

    {

    [Display(Name = "用户编号")]

    public
    Guid Userid { get; set; }

    [Display(Name = "用户姓名")]

    public
    string Name { get; set; }

    [Display(Name = "用户年龄")]

    public
    int? Age { get; set; }

    }

    }

    再看看页面


  4. 加一下验证

????改成中文验证

????????????[Display(Name = "用户姓名")]

????????[StringLength(10, MinimumLength = 3,ErrorMessage = "字段{0}长度不能小于3,总长度不能大于10")]

????????[Required]

????public
string Name { get; set; }

????

  1. 最后就是部署到Ubuntu服务器了。

    将WebApp项目发布出来,使用SSH Secure File Transfer上传到服务器,然后参照前文发布。

    前文:http://blog.csdn.net/lanwilliam/article/details/51880124

总结:

????Asp.net Core 目前来说功能性还不完善,暂时不建议大型应用往上迁移,但是如果是小型项目,比较简单,可以在仔细论证后尝试使用。注意仔细论证,因为目前.net core并不是所有类库都能够实现跨平台。简单来说,System.Drawing就无法使用,所以后台画水印就需要其他三方库,这个请自行仔细论证。不过小项目发布到linux虚拟机上面,确实可以省一笔钱。

时间: 2024-11-08 18:21:03

Asp.net Core基于MVC框架实现PostgreSQL操作的相关文章

ASP.NET Core 配置 MVC - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 配置 MVC - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 MVC 前面几章节中,我们都是基于 ASP.NET 空项目 模板创建的 HelloWorld 上做开发 通过这个最基本的 HelloWorld 项目,我们了解了很多知识,初窥了 ASP.NET Core,并对 ASP.NET Core 的运行机制有了一个基本的了解 MVC 模式是 Web 开发中最重要的一个模式之一,通过 MVC,我们可以将控制器.模型和视

ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 EF 框架服务 上一章节中我们了解了 Entity Framework 的基本工作原理和 DbContext ,我们也创建了一个自己的 HelloWorldDBContext. 本章节我们就来讲讲如何设置我们的 EF 框架来链接到 SQLite 数据库 配置 EF 框架服务 要让我们的 EF 框架的 DBContext 能够运行起来,我们需要更改一

ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 使用 EF 框架查询数据 上一章节我们学习了如何设置和初始化数据库,以及如何创建迁移代码和应用迁移代码.本章节我们就学习如何使用 EF 框架来查询数据库,至于添加和修改,后面的章节中我们会慢慢学习到 添加测试数据 我们首先使用 SQLite Studio 添加三条数据 ID Name 1 李白 2 杜甫 3 白居易 使用 SQLite Studio

ASP.NET Core微服务框架Ocelot+Consul+IdentityServer4实战演练

一.背景介绍 API网关的流行源于最近几年移动应用与企业间接口对接的兴起,使得原来单一的PC客户端,变化到PC客户端.各种浏览器.手机移动端及智能终端等.同时系统之间大部分都不是单独运行,经常会涉及与其他系统对接.共享数据的需求.随着微服务架构概念的提出,API网关成为了微服务架构的一个标配组件.随着业务快速发展,面向手机移动应用业务越来越多,为了减少客户端与服务的耦合,节约后端微服务的开发成本,建立一个高性能.高可用.减少上线风险的API网关成为一个迫切的需求. 1).目前面临现状:假设你正好

基于MVC框架的新闻信息发布系统设计与实现——论文随笔(十三)

一.基本信息 标题:基于MVC框架的新闻信息发布系统设计与实现 时间:2015-05 出版源:东北大学 领域分类:系统架构和设计 二.研究背景 问题定义:随着信息化社会的快速发展和Internet的普及 ,上网查阅新闻信息的人越来越多.新闻发布系统的用户是相当惊人的,其重要性是不容置疑的,当然这也对新闻发布系统的开发提出了更髙更严格的要求. 相关工作:本文提出开发一个新闻发布系统的想法 ,以解决传统获取新闻过程中所产生的诸多不便的问题,同时,也可为商业网站与外界实现更好的沟通 ,创造更多 的商业

.Net Core 基于CAP框架的事件总线

.Net Core 基于CAP框架的事件总线 CAP 是一个在分布式系统中(SOA,MicroService)实现事件总线及最终一致性(分布式事务)的一个开源的 C# 库,她具有轻量级,高性能,易使用等特点. github:https://github.com/dotnetcore/CAP doc:http://cap.dotnetcore.xyz CAP是一款优秀的框架,但是CAP在消息订阅的处理类必须使用[CapSubscribe]特性来绑定,本人觉得不是很科学. 好在2.5.1版本开放了接

ASP.NET Core开发-MVC 使用dotnet 命令创建Controller和View

使用dotnet 命令在ASP.NET Core MVC 中创建Controller和View,之前讲解过使用yo 来创建Controller和View. 下面来了解dotnet 命令来创建Controller和View,功能更加强大,更加完整. 结合VS Code 使你能跨平台更好更快速的开发 ASP.NET Core MVC. 也就可以在 Linux 和Mac 中更好的开发ASP.NET Core 应用程序. 创建ASP.NET Core应用程序 dotnet new -t web dotn

Building microservices with ASP.NET Core (without MVC)(转)

There are several reasons why it makes sense to build super-lightweight HTTP services (or, despite all the baggage the word brings, “microservices”). I do not need to go into all the operational or architectural benefits of such approach to system de

【ASP.NET Core】MVC中自定义视图的查找位置

.NET Core 的内容处处可见,刷爆全球各大社区,所以,老周相信各位大伙伴已经看得不少了,故而,老周不考虑一个个知识点地去写,那样会成为年度最大的屁话,何况官方文档也很详尽.老周主要扯一下大伙伴们在入门的时候可能会疑惑的内容. ASP.NET Core 可以在一个项目中混合使用 Web Pages 和 MVC ,这是老周最希望的,因为这样会变得更灵活.Web Pages 类似于我们过去的 Web 开发方式,以页面为单位,此模型侧重于功能划分.而 MVC 侧重于数据,有什么样的数据模型就有什么