.Net Core开发学习(三) ——Mvc应用

.Net Core开发学习(三) ——Mvc应用


Mvc概念

Mvc分别为Model、View、Controller,分工不同

模型(Model):为应用程序提供并绑定数据,为业务逻辑与视图显示提供支持。
视图(View):为应用程序提供前端数据显示与数据绑定。
控制器(Controller):处理请求。


创建项目

创建项目1
创建项目2

项目结构

项目结构

项目相关文件与Web应用相似,可参考.Net Core开发学习(二) ——Web应用

文件夹Models:存放模型(Model)
文件夹Views:存放视图(View)
文件夹Controllers:存放控制器(Controller)


添加控制器(Controller)

添加控制器: 项目 > 右键Controllers > 添加 > 新建项 > 控制器类 > 修改名称(HelloController) > 确定

HelloController文件内容如下:

public class HelloController : Controller
{
    // GET: /<controller>/
    public IActionResult Index()
    {
        return View();
    }
}

现在是不能运行的,因为Index方法返回的是一个视图,而我们还没有创建对应的视图文件,所以会报InvalidOperationException错误。

让我们改一下Index方法

public string Index()
{
    return "HelloWorld";
}

运行结果

HelloWorld

现在我们来加点参数,添加如下方法

public string Hello(string name)
{
    return "Hello " + name;
}

请求并Url传参/Hello/Hello?name=ZiYun,运行结果

Hello ZiYun

但带参数名的传参不太美观,且可能影响安全性。没关系,我们可以使用路由。

在Hello()方法上加上Route属性

//添加路由,参数为路由的路径
[Route("Hello/Hello/{name}")]
public string Hello(string name)
{
    return "Hello " + name;
}

请求并Url传参/Hello/Hello/ZiYun,运行结果

Hello ZiYun

添加视图(View)

首先我们将HelloController.cs的Index方法改回来

public IActionResult Index()
{
    return View();
}

添加视图: 右键Views文件夹 > 新建文件夹(Hello) > 右键Hello文件夹 > 添加 > 新建项 > Razor 视图文件 > 命名(Index.cshtml) > 确定

添加完成后视图是没有内容的,我们添加一点内容

@{
    ViewData["Title"] = "Hello Index";
}

<h2>Hello Index</h2>

请求/Hello,运行结果
/Hello运行结果

将数据传递给页面

修改代码 HelloController.cs > Index()

public IActionResult Index()
{
    ViewData["name"] = "ZiYun";
    return View();
}

修改视图 Views > Hello >

@{
    ViewData["Title"] = "Hello Index";
}

<h2>Hello @ViewData["name"]</h2>

请求/Hello,运行结果

/Hello运行结果1

添加模型(Model)

新建类:Models > User.cs

结构如下

public class User
{
    public int ID { get; set; }

    [Required(ErrorMessage = "用户名不能为空")]
    public string Name { get; set; }

    [Required(ErrorMessage = "请输入正确的日期")]
    [DataType(DataType.Date, ErrorMessage = "请输入正确的日期")]
    public DateTime Birthday { get; set; }
}

打开:菜单栏 > NuGet 包管理器 > 包管理器控制台(PMC)

输入以下命令安装Sqlserver数据驱动

Install-Package Microsoft.EntityFrameworkCore.SqlServer

新建数据上下文类:Data > WebApplicationContext.cs

结构如下

public class WebApplicationContext : DbContext
{
    public WebApplicationContext(DbContextOptions<WebApplicationContext> options) : base(options) 
    { 
    
    }

    public DbSet<User> User { get; set; }
}

配置DbContext服务

修改文件:Startup.cs > ConfigureServices()

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
	//注册数据上下文
    services.AddDbContext<WebApplicationContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("WebApplicationContext")));
}

修改文件:appsettings.json

将连接字符串添加到第一个大括号内

  "ConnectionStrings": {
    "WebApplicationContext": "Server=(localdb)\\mssqllocaldb;Database=WebApplication1-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }

数据迁移:菜单栏 > 工具(Tools) > Nuget包管理器(NPM) > 程序包管理控制台(PMC)

输入以下命令:

Add-Migration Initial
Update-Database

命令解释:
Add-Migration:添加迁移文件,根据创建的数据上下文,添加创建数据库及结构的代码。Initial为迁移名,可自行定义。执行完成后会弹出创建数据库的文件Migrations/<time-stamp>_Initial.cs。可根据实际情况进行更改。
Update-Database:根据迁移文件更新数据库。

这样我们的数据源就配置好了

添加测试界面

新建文件夹:Views > Users
新建基架:右键Users文件夹 > 新搭建基架的项目 > 视图使用Entity Framework 的 MVC 控制器 > 模型类(User) > 数据上下文类(WebApplicationContext) > 确定

可以看到已经帮我们添加好了增删改查页面以及UsersController控制器
Users结构
运行项目,测试增删改查

Mvc的数据请求与数据绑定

在Mvc中通过控制器来处理页面请求和查询数据,Web应用通过Razor页面代码(.cshtml.cs)来处理。

查看Action:UsersController > [HttpGet]Edit

public async Task<IActionResult> Edit(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var user = await _context.User.FindAsync(id);
    if (user == null)
    {
        return NotFound();
    }
    return View(user);
}

当请求Edit Action时,控制器返回一个User对象,返回类型为 Task<IActionResult> 表示 异步处理同步 使用 IActionResult

查看文件:Views > Users > Edit.cshtml

@model WebApplication1.Models.User

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>User</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="ID" />
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Birthday" class="control-label"></label>
                <input asp-for="Birthday" class="form-control" />
                <span asp-validation-for="Birthday" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

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

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

@model WebApplication1.Models.User :声明当前视图需要的数据类型
asp-for:绑定模型数据

其他获取数据方式
@Html.DisplayNameFor(model => model.Name)
@Html.DisplayFor(model => model.Name)
@Model.Name


查看Action:UsersController > [HttpPost]Edit

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Name,Birthday")] User user)
{
    if (id != user.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(user);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!UserExists(user.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(user);
}

可以看到,在Mvc中提交绑定数据需要手动设置一下 [Bind()] ,其他操作和Web应用差距不大。

查看Action:UsersController > Delete() 以及 DeleteConfirmed()

// GET: Users/Delete/5
public async Task<IActionResult> Delete(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var user = await _context.User
        .FirstOrDefaultAsync(m => m.ID == id);
    if (user == null)
    {
        return NotFound();
    }

    return View(user);
}

// POST: Users/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
    var user = await _context.User.FindAsync(id);
    _context.User.Remove(user);
    await _context.SaveChangesAsync();
    return RedirectToAction(nameof(Index));
}

注意:
我们发现Delete的Post方法被命名成DeleteConfirmed,其实是因为如果写Delete,因为命名一致,参数一致会造成二义性。解决方法就是将修改命名,添加属性ActionName写上需要的Action名。

OK,一个简单的.Net Core Mvc项目就完成啦。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值