ASP.NET MVC 入门指南二

9. 表单处理与提交

9.1 创建表单视图

在视图文件夹下创建一个用于创建产品的视图,如 Create.cshtml

html

复制代码
@model YourNamespace.Product

@{
    ViewBag.Title = "创建产品";
}

<h2>创建产品</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>产品信息</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="创建" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("返回列表", "Index")
</div>

这个视图使用 Razor 语法创建了一个表单,用于输入产品的名称和价格,并提供了提交按钮。

9.2 处理表单提交

在控制器中添加处理表单提交的方法:

复制代码
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Name,Price")] Product product)
{
    if (ModelState.IsValid)
    {
        db.Products.Add(product);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(product);
}

这个方法使用 [HttpPost] 特性来处理 POST 请求,使用 [ValidateAntiForgeryToken] 来防止跨站请求伪造。如果模型验证通过,将产品添加到数据库并保存更改,然后重定向到产品列表页面;否则,返回创建视图并显示错误信息。

10. 控制器中的动作方法

10.1 动作方法的返回类型
  • ViewResult :返回一个视图。例如 return View();return View(model);
  • RedirectToRouteResult :重定向到另一个路由。例如 return RedirectToAction("Index", "Product");
  • JsonResult :返回 JSON 数据。例如 return Json(data, JsonRequestBehavior.AllowGet);
  • ContentResult :返回纯文本内容。例如 return Content("Hello, World!");
10.2 动作方法的参数绑定

动作方法可以接收不同类型的参数,如简单类型(intstring 等)、复杂类型(模型类)和路由数据。例如:

csharp

复制代码
public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Product product = db.Products.Find(id);
    if (product == null)
    {
        return HttpNotFound();
    }
    return View(product);
}

这个方法接收一个可选的 int 类型的 id 参数,用于查找并显示特定产品的详细信息。

11. 视图引擎与 Razor 语法

11.1 视图引擎

ASP.NET MVC 默认使用 Razor 视图引擎。视图引擎负责将视图文件转换为 HTML 页面。可以通过配置文件或代码来切换视图引擎。

11.2 Razor 语法
  • 表达式 :使用 @ 符号输出表达式的值。例如 @DateTime.Now 输出当前时间。
  • 代码块 :使用 @{ ... } 包含代码块。例如:

html

复制代码
@{
    var message = "Hello, Razor!";
}
<p>@message</p>
  • 条件语句和循环语句 :可以在视图中使用 ifforforeach 等语句。例如:

html

复制代码
@if (Model.Count > 0)
{
    <ul>
        @foreach (var item in Model)
        {
            <li>@item.Name</li>
        }
    </ul>
}
else
{
    <p>没有数据。</p>
}

12. 过滤器

12.1 过滤器的类型
  • 授权过滤器 :用于验证用户是否有权限访问某个动作方法。例如 [Authorize] 特性。
  • 动作过滤器:在动作方法执行前后执行代码。可以自定义动作过滤器类。
  • 结果过滤器:在动作结果执行前后执行代码。
  • 异常过滤器:在发生异常时执行代码,用于处理错误。
12.2 自定义过滤器

以下是一个自定义动作过滤器的示例:

csharp

复制代码
public class CustomActionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // 在动作方法执行前执行的代码
        filterContext.HttpContext.Response.Write("动作方法即将执行...<br />");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // 在动作方法执行后执行的代码
        filterContext.HttpContext.Response.Write("动作方法已执行。<br />");
        base.OnActionExecuted(filterContext);
    }
}

可以在控制器或动作方法上使用这个过滤器:

csharp

复制代码
[CustomActionFilter]
public ActionResult Index()
{
    return View();
}

13. 依赖注入与服务定位

13.1 依赖注入的概念

依赖注入(DI)是一种设计模式,用于解耦对象之间的依赖关系。在 ASP.NET MVC 中,可以使用依赖注入来管理控制器的依赖项。

13.2 使用依赖注入

可以使用第三方依赖注入容器,如 Autofac 或 Microsoft.Extensions.DependencyInjection。以下是使用 Microsoft.Extensions.DependencyInjection 的示例:

csharp

复制代码
// 在 Startup.cs 中配置依赖注入
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ProductContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddControllersWithViews();
}

然后在控制器中使用构造函数注入:

csharp

复制代码
public class ProductController : Controller
{
    private readonly ProductContext _db;

    public ProductController(ProductContext db)
    {
        _db = db;
    }

    // 动作方法...
}

14. 测试 MVC 应用程序

14.1 单元测试

可以使用单元测试框架,如 NUnit 或 MSTest,对控制器和模型进行单元测试。例如,测试控制器的动作方法:

复制代码
[Test]
public void Index_ReturnsAViewResult_WithAListOfProducts()
{
    // Arrange
    var mockDb = new Mock<ProductContext>();
    var products = new List<Product>
    {
        new Product { Id = 1, Name = "产品1", Price = 10.0m },
        new Product { Id = 2, Name = "产品2", Price = 20.0m }
    };
    mockDb.Setup(m => m.Products).Returns(products.AsQueryable());
    var controller = new ProductController(mockDb.Object);

    // Act
    var result = controller.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result);
    var model = result.Model as List<Product>;
    Assert.IsNotNull(model);
    Assert.AreEqual(2, model.Count);
}
14.2 集成测试

集成测试用于测试多个组件之间的交互,如控制器、视图和数据库。可以使用 Selenium 等工具进行端到端测试。

15. 部署与发布

15.1 发布到 IIS

可以使用 Visual Studio 的发布功能将应用程序发布到 Internet Information Services (IIS)。在发布配置中选择目标服务器和发布方式,然后点击 "发布" 按钮。

15.2 发布到云服务

也可以将应用程序发布到云服务,如 Azure 或 AWS。这些云服务提供了方便的部署和管理工具。

通过以上内容,你对 ASP.NET MVC 有了更深入的了解,可以进一步开发复杂的 Web 应用程序。记得在实际开发中不断实践和探索,以掌握更多的技巧和最佳实践。

相关推荐
互联网打工人no112 分钟前
.NET8 依赖注入组件
开发语言·c#·.net·ioc
fs哆哆19 分钟前
在VB.net和VBA中,自定义函数GetTargetSheet()返回工作表对象
java·开发语言·前端·javascript·ecmascript
好_快30 分钟前
Lodash源码阅读-uniqBy
前端·javascript·源码阅读
好_快34 分钟前
Lodash源码阅读-uniqWith
前端·javascript·源码阅读
恋猫de小郭1 小时前
Flutter Widget IDE 预览新进展,开始推进落地发布
android·前端·flutter
jingling5552 小时前
【Vue3 实战】插槽封装与懒加载
前端·javascript·vue.js
Freedom风间8 小时前
前端优秀编码技巧
前端·javascript·代码规范
萌萌哒草头将军8 小时前
🚀🚀🚀 Openapi:全栈开发神器,0代码写后端!
前端·javascript·next.js
程序设计实验室8 小时前
一次小而美的重构:使用 C# 在 Avalonia 中生成真正好看的词云
c#
萌萌哒草头将军8 小时前
🚀🚀🚀 Prisma 爱之初体验:一款非常棒的 ORM 工具库
前端·javascript·orm