namespace AspNetCore.Controllers.Controllers { public class HomeController : Controller { private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger) { _logger = logger; } public IActionResult Index() { return View(); } public IActionResult Privacy() { return View(); } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } } }这里有几点需要注意:
using Microsoft.AspNetCore.Mvc; namespace AspNetCore.Controllers.Controllers { public class HomeController : Controller { // 堆代码 duidaima.com private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger) { _logger = logger; } public IActionResult Index() { return View(); } } }HomeController中的Index方法有自己对应的视图文件Index.cshtml,该文件位于View->Home文件夹下
@{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p> </div>视图包含两种类型的代码:
@{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <p>Welcome from <b>Index View</b> of <b>Home Controller</p> </div>运行你应用程序,你将会看到这个视图呈现在浏览器中
public IActionResult SomeAction() { ViewData["Name"] = "GuiBingBing"; ViewData["Address"] = new Address { HouseNo = "", City = "" }; return View(); }现在在视图上,我展示2个ViewData对象中的值:
@{ // casting address to Address.cs class object var address = ViewData["Address"] as Address; } <p>Hello: @ViewData["Name"]</p> <p>With Address: @address.HouseNo, @address.City</p>
HttpRequest包含Form属性,返回一个FormData对象的字典,你可以使用Form属性读取从View传输过来的数据创建一个表单在视图上并且在控制器中接收数据。
我们修改一下HomeController的Index视图:
@{ ViewData["Title"] = "Home Page"; } <form class="form-horizontal" method="post" asp-action="ReceivedDataByRequest"> <div class="mb-3 row"> <div class="col-sm-1"> <label>名称:</label> </div> <div class="col-sm-11"> <input class="form-control" name="name" /> </div> </div> <div class="mb-3 row"> <div class="col-sm-1"> <label>性别:</label> </div> <div class="col-sm-11"> <select class="form-control" name="sex"> <option value="M">Male</option> <option value="F">Female</option> </select> </div> </div> <div class="mb-3 row"> <div class="col-sm-11 offset-sm-1"> <button type="submit" class="btn btn-primary">提交</button> </div> </div> </form>在表单上使用Bootstrap的样式表,来改善表单呈现效果。
public IActionResult ReceivedDataByRequest() { var name = Request.Form["name"]; var sex = Request.Form["sex"]; return View("ReceivedDataByRequest", $"{name} sex is {sex}"); }我们在action方法中使用Request.Form获取表单的值,它返回表单数据字典,因此Request.Form["name"]通过name的名字来获取表单控件输入的值,相同的方式Request.Form["sex"]通过name获取选择空间的值。
View("ReceivedDataByRequest", $"{name} sex is {sex}");第一个参数表示呈现的视图的名称,第二个参数传输到View的数据,现在我们针对这个方法创建一个视图文件,因此右击Views->Home文件夹并且选择Add->New Item,然后对话框选择。
@model string <h1>@Model</h1>这个视图相对简单并且包含了2行代码,视图接收一个字符串数据(看action方法最后一行View()方法的第二个参数),因此我定义一个模型为-@model string , 最后我们在h1标签中展示数据 - @Model(注意首字母大写),因此,无论我们从action方法传递什么,这个View都会在h1标签中显示它
public IActionResult ReceivedDataByParameter(string name, string sex) { return View("ReceivedDataByParameter", $"{name} sex is {sex}"); }注意action方法的两个参数-name&sex, 他们的名字和控件的名字是相同的这点需要注意,因为name和sex的值是字符串类型,我们需要提供2个字符串类型的值,如果你想访问一个新的字段"age"的值你需要在action方法中添加一个新的int类型的参数。
public IActionResult ReceivedDataByParameter(string name, string sex) { return View("ReceivedDataByParameter", $"{name} sex is {sex}"); }最后,添加一个新的Razor视图在Views->Home文件夹,命名为ReceivedDataByParameter,这个视图将显示如下信息
@model string <h1>@Model</h1>运行应用程序并在表单中输入数据,点击提交按钮,你将看到你表单信息显示在浏览器中. 图片如下:
<a href="/Home/ReceivedDataByParameter?name=jack sparrow&sex=m" class="link-primary">Primary link</a>单击此锚点标记时,查询字符串将携带姓名和性别值,ReceivedDataByParameter操作方法的参数将接收这些值
namespace AspNetCore.Controllers.Models { public class Person { public string name { get; set; } public string sex { get; set; } } }这个类中有2个属性,.NET 会使用View中html控件的值自动填充这两个属性。接下来在HomeController中加一个新的action方法ReceivedDataByModelBinding,代码如下:
public IActionResult ReceivedDataByModelBinding(Person person) { return View("ReceivedDataByModelBinding", person); }这个方法有一个Person类型的参数,因此.NET 使用了模型绑定技术,在最后一行代码中将Person对象的数据传递给ReceivedDataByModelBinding视图,因此,意味着这个View将接收一个Person类型。在Views->Home文件夹中创建一个ReceivedDataBy-ModelBinding视图,这个视图相对比较简单,他接收Person类型并显示Person类中name和sex属性的值。
@model Person <h1>@Model.name sex is @Model.sex</h1>我们接下来进入最后部分,为了让ASP.NET Core运行时能更好将表单和实体类做映射,因此我们需要更新一下Index视图中的表单,修改的代码如下:
@model Person @{ ViewData["Title"] = "Home Page"; } @*<form class="form-horizontal" method="post" asp-action="ReceivedDataByRequest">*@ @*<form class="form-horizontal" method="post" asp-action="ReceivedDataByParameter">*@ <form class="form-horizontal" method="post" asp-action="ReceivedDataByModelBinding"> <div class="mb-3 row"> <div class="col-sm-1"> <label>名称:</label> </div> <div class="col-sm-11"> @*<input class="form-control" name="name" />*@ <input class="form-control" asp-for="name" /> </div> </div> <div class="mb-3 row"> <div class="col-sm-1"> <label>性别:</label> </div> <div class="col-sm-11"> @*<select class="form-control" name="sex">*@ <select class="form-control" asp-for="sex"> <option value="M">Male</option> <option value="F">Female</option> </select> </div> </div> <div class="mb-3 row"> <div class="col-sm-11 offset-sm-1"> <button type="submit" class="btn btn-primary">提交</button> </div> </div> </form>这里需要注意几点
<form method="post" enctype="multipart/form-data"> <div class="form-group"> <label>Photo:</label> <input type="file" class="form-control" name="photo" /> </div> <div class="m-1"> <button class="btn btn-primary" type="submit">Upload</button> </div> </form>接下来在Home控制器中添加一个Post版本的Index方法并且包含了IFormFile photo参数获取上传的文件,我们上传这个文件到wwwroot文件因此我必须注入IWebHostEnvironment在控制器的构造函数中
[HttpPost] public async Task<IActionResult> Index(IFormFile photo) { using (var stream = new FileStream(Path.Combine(_hostingEnvironment.WebRootPath, photo.FileName), FileMode.Create)) { await photo.CopyToAsync(stream); } return View(); }总结