实现步骤 :
1、创建一个空白的项目
2、创建一个.NET Core 项目,选择API,记得把https勾选去掉
①、
然后导入EF Core相关包,点右键选择NuGet包管理,找到一下几个下载即可
Microsoft.EntityFrameworkCore.SqlServer:Sql Server数据库EF提供程序
Microsoft.EntityFrameworkCore.Design:设计时EF共享库
Microsoft.EntityFrameworkCore.Tools:EF的NuGet包管理器命令工具
②、选择程序包管理器控制台
输入:
Scaffold-DbContext 'Data Source=.;Initial Catalog=bookshopdb; Integrated Security=True;' Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context ShopContext
就可以生成实体类
③、找到appsettings.json文件,添加:
cs
"ConnectionStrings": {
"shopdb": "Data Source=.;Initial Catalog=bookshopdb;Integrated Security=True"
},
④、在Startup.cs 文件里面的ConfigureServices方法里面,添加上下文和 添加跨域服务
cs
//注册上下文
services.AddDbContext<ShopContext>(option =>
{
option.UseSqlServer(Configuration.GetConnectionString("shopdb"));
});
//添加跨域服务
services.AddCors(option =>
{
option.AddPolicy(MyCorsPolicy, builder =>
{
//声明跨域策略:允许所有域 允许所有表头 允许所有方法
builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
在ConfigureServices方法上面,添加:
readonly string MyCorsPolicy = "CorsPolicy";
在Configure方法里面,添加使用允许跨域请求
cs
//使用允许跨域请求
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireCors(MyCorsPolicy);
});
⑤、在控制器上方点右键添加,选择控制器,在选择其操作使用Entity Framework的API 控制器,把三个表的实体模型都生成控制器的对应接口(偷懒模式)
⑥、在UsersController(对应的是用户实体类)控制器添加一个登录的方法
这里要注意,.net core 的 post 方法比较坑,需要在接收参数的时候,添加上[FromFrom] 不然参数接收不到
三张表,另外的类型和书籍很简单,直接按照上面的方法,自动生产即可,不需要添加方法
3、添加新项目,选择ASP.NET Core 选择Web应用程序(模型视图控制器)
在Home控制器添加一个 public IActionResult Login()
{
return View();
}
方法,点击右键,添加视图
Login.cshtml
cs
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>登录</title>
<link href="~/css/antd.min.css" rel="stylesheet" />
<script src="~/js/vue.min.js"></script>
<script src="~/js/axios.min.js"></script>
<script src="~/js/antd.min.js"></script>
<style>
#app {
width: 500px;
margin: 20px auto;
box-shadow: 0 0 8px #676767;
padding: 20px;
line-height: 35px;
}
</style>
</head>
<body>
<div id="app">
<h3>用户登录</h3>
<p>
<a-input v-model="name">
<span slot="addonBefore">账号</span>
</a-input>
</p>
<p>
<a-input v-model="pwd" type="password">
<span slot="addonBefore">密码</span>
</a-input>
</p>
<p class="text-center">
<a-button type="primary" v-on:click="login">登录</a-button>
</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
name: "",
pwd: "",
},
methods: {
login() {
let params = new URLSearchParams();
params.append('name', this.name);
params.append('pwd', this.pwd);
axios({
method: 'post',
url: 'http://localhost:5000/api/Users/PostLogin',
data: params
}).then(res => {
if (res.data == '登录成功') {
location.href = "/Home/Index";
}
});
}
}
})
</script>
</body>
</html>
注意:执行的时候,先执行webapi的项目,选择执行不调试,然后在选择mvc的项目设为启动项,执行不调试,可能会端口号冲突,这里就需要Properties 文件夹下面的launchSettings.json文件,找到对应自己的mvc项目名称,修改applicationUrl后面的端口号即可
Index.cshtml
html
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="~/css/antd.min.css" rel="stylesheet" />
<script src="~/js/vue.min.js"></script>
<script src="~/js/axios.min.js"></script>
<script src="~/js/antd.min.js"></script>
<style>
.logo {
width: 220px;
height: 31px;
margin: 16px 24px 16px 0;
float: left;
text-align: center;
line-height: 31px;
font-weight: bold;
}
dl {
box-shadow: 0 0 8px #676767;
padding: 20px;
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<div id="layout-basic">
<a-layout>
<a-layout-header class="header">
<div class="logo">在线书店</div>
<a-menu mode="horizontal" :defaultSelectedKeys="['2']" :style="{lineHeight:'64px'}">
<a-menu-item key="1">欢迎访问</a-menu-item>
</a-menu>
</a-layout-header>
<a-layout>
<a-layout-sider>
<a-menu mode="inline" theme="dark">
<a-sub-menu key="sub1">
<span slot="title">
<span>图书分类</span>
</span>
<a-menu-item key="1">全部分类</a-menu-item>
<a-menu-item v-for="item in catelist" v-on:click="search" :key="item.name">{{item.name}}</a-menu-item>
</a-sub-menu>
</a-menu>
</a-layout-sider>
<a-layout style="padding:0 24px 24px">
<p>
<a-input v-model="catename">
<span slot="addonBefore">在全部分类中搜索:</span>
</a-input>
</p>
<a-layout-content :style="{backgroundColor:'#fff',padding:'24px',maring:0}">
<a-row>
<a-col span="6" v-for="book in filterBooks" :key="book.id">
<dl>
<dt>
<img :src="'../images/'+book.picture" width="100" height="100" />
</dt>
<dd>
<h3> {{book.title}}</h3>
</dd>
<dd>
¥ {{book.price}}
</dd>
</dl>
</a-col>
</a-row>
</a-layout-content>
</a-layout>
</a-layout>
<a-layout-footer>底部:版权</a-layout-footer>
</a-layout>
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
catename: "",
img:'',
catename: "",
booklist: [],
catelist: []
},
created: function () {
var t = this;
axios.get("http://localhost:5000/api/Categories").then(function (res) {
var result = res.data;
t.catelist = result;
}).catch(function (err) {
console.log(err);
})
axios.get("http://localhost:5000/api/Books").then(function (res) {
var result = res.data;
console.log(res.data);
t.booklist = result;
}).catch(function (err) {
console.log(err);
})
},
computed: {
filterBooks: function () {
var t = this;
console.log(this.booklist.picture);
return this.booklist.filter(function (item) {
return item.title.indexOf(t.catename) != -1;
})
}
},
methods: {
search: function (e) {
return this.booklist.filter(function (item) {
return item.categoryName.indexOf(e.key) != -1;
})
}
}
})
</script>
</body>
</html>
注意:img的src路径 <img :src="'../images/'+book.picture" width="100" height="100" />,标签里面不能使用{{}}所以需要拼接的方式,还又src前面的:不能漏掉,等同于v-bind:src ,两个页面都没有使用模板,设置的@{
Layout = null;
}
如果要使用模板的话,就需要@section Script{ 引用css和js,写js的代码}