当前位置: 首页 > news >正文

ASP.NET MVC​ 入门指南四

21. 高级路由配置

21.1 自定义路由约束

除了使用默认的路由约束,你还可以创建自定义路由约束。自定义路由约束允许你根据特定的业务逻辑来决定一个路由是否匹配。例如,创建一个只允许特定年份的路由约束:

csharp

public class YearRouteConstraint : IRouteConstraint
{public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection){if (values.TryGetValue(routeKey, out object value)){if (int.TryParse(value.ToString(), out int year)){return year >= 2000 && year <= 2030;}}return false;}
}

然后在路由配置中使用这个自定义约束:

routes.MapRoute(name: "CustomYearRoute",url: "products/{year}",defaults: new { controller = "Product", action = "Index" },constraints: new { year = new YearRouteConstraint() }
);
21.2 区域路由

当应用程序变得复杂时,可以使用区域(Areas)来组织代码。区域允许你将相关的控制器、视图和模型分组在一起。创建一个区域的步骤如下:

  • 在项目中创建一个 Areas 文件夹。
  • 在 Areas 文件夹下创建一个新的区域文件夹,例如 Admin
  • 在 Admin 文件夹下创建 ControllersViews 和 Models 文件夹。
  • 在 Admin 文件夹下创建一个 AdminAreaRegistration.cs 文件来配置区域路由:

public class AdminAreaRegistration : AreaRegistration
{public override string AreaName{get{return "Admin";}}public override void RegisterArea(AreaRegistrationContext context){context.MapRoute("Admin_default","Admin/{controller}/{action}/{id}",new { action = "Index", id = UrlParameter.Optional });}
}

在 RouteConfig.cs 中注册区域:

public class RouteConfig
{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");// 注册区域AreaRegistration.RegisterAllAreas();routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}
}

22. 视图组件

22.1 视图组件的概念

视图组件是一种轻量级的可复用视图元素,类似于部分视图,但功能更强大。视图组件可以包含自己的逻辑和数据访问代码,并且可以异步加载。

22.2 创建视图组件

创建一个视图组件需要以下步骤:

  • 创建一个继承自 ViewComponent 的类,例如:

public class LatestProductsViewComponent : ViewComponent
{private readonly ProductContext _context;public LatestProductsViewComponent(ProductContext context){_context = context;}public async Task<IViewComponentResult> InvokeAsync(){var latestProducts = await _context.Products.OrderByDescending(p => p.CreatedDate).Take(5).ToListAsync();return View(latestProducts);}
}

  • 在 Views/Shared/Components/LatestProducts 文件夹下创建一个 Default.cshtml 视图文件:

@model IEnumerable<YourNamespace.Product><h3>最新产品</h3>
<ul>@foreach (var product in Model){<li>@product.Name</li>}
</ul>

  • 在其他视图中使用视图组件:

@await Component.InvokeAsync("LatestProducts")

23. 信号量与实时通信

23.1 使用 SignalR 实现实时通信

SignalR 是一个用于在服务器和客户端之间实现实时通信的库。可以使用 SignalR 来创建实时聊天、实时通知等功能。

  • 安装 Microsoft.AspNetCore.SignalR 包。
  • 创建一个继承自 Hub 的类,例如:

public class ChatHub : Hub
{public async Task SendMessage(string user, string message){await Clients.All.SendAsync("ReceiveMessage", user, message);}
}

  • 在 Startup.cs 中配置 SignalR:

public void ConfigureServices(IServiceCollection services)
{services.AddSignalR();services.AddControllersWithViews();
}public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{// 其他配置...app.UseEndpoints(endpoints =>{endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");endpoints.MapHub<ChatHub>("/chatHub");});
}

  • 在客户端使用 JavaScript 连接到 SignalR 服务器:

html

<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.1/signalr.min.js"></script>
<script>const connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();connection.on("ReceiveMessage", (user, message) => {const msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");const encodedMsg = user + " says: " + msg;const li = document.createElement("li");li.textContent = encodedMsg;document.getElementById("messagesList").appendChild(li);});connection.start().catch(err => console.error(err.toString()));document.getElementById("sendButton").addEventListener("click", event => {const user = document.getElementById("userInput").value;const message = document.getElementById("messageInput").value;connection.invoke("SendMessage", user, message).catch(err => console.error(err.toString()));event.preventDefault();});
</script>

24. 日志记录与监控

24.1 日志记录

在 ASP.NET MVC 中,可以使用 Microsoft.Extensions.Logging 进行日志记录。在 Startup.cs 中配置日志记录:

public void ConfigureServices(IServiceCollection services)
{services.AddLogging(loggingBuilder =>{loggingBuilder.AddConsole();loggingBuilder.AddDebug();});services.AddControllersWithViews();
}

在控制器中使用日志记录:

private readonly ILogger<ProductController> _logger;public ProductController(ILogger<ProductController> logger)
{_logger = logger;
}public ActionResult Index()
{_logger.LogInformation("访问产品列表页面");return View();
}
24.2 监控

可以使用 Application Insights 来监控应用程序的性能和健康状况。在 Startup.cs 中配置 Application Insights:

public void ConfigureServices(IServiceCollection services)
{services.AddApplicationInsightsTelemetry(Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"]);services.AddControllersWithViews();
}

Application Insights 可以收集应用程序的请求数据、异常信息、性能指标等,帮助你快速发现和解决问题。

25. 微服务架构与 MVC

25.1 微服务架构概述

微服务架构是一种将应用程序拆分为多个小型、自治服务的架构模式。每个微服务都可以独立开发、部署和扩展。

25.2 在 MVC 中集成微服务

可以将 MVC 应用程序拆分为多个微服务,每个微服务负责一个特定的业务功能。例如,将产品管理、订单管理、用户管理等功能拆分为独立的微服务。可以使用 RESTful API 来实现微服务之间的通信。

// 产品微服务的控制器
[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{private readonly ProductContext _context;public ProductController(ProductContext context){_context = context;}[HttpGet]public async Task<ActionResult<IEnumerable<Product>>> GetProducts(){return await _context.Products.ToListAsync();}
}

在其他微服务中调用产品微服务的 API:

using System.Net.Http;
using System.Threading.Tasks;public class ProductService
{private readonly HttpClient _httpClient;public ProductService(HttpClient httpClient){_httpClient = httpClient;}public async Task<IEnumerable<Product>> GetAllProducts(){var response = await _httpClient.GetAsync("http://product-service/api/product");response.EnsureSuccessStatusCode();return await response.Content.ReadAsAsync<IEnumerable<Product>>();}
}

通过以上这些高级内容的学习,你可以进一步提升自己在 ASP.NET MVC 开发方面的技能,应对更复杂的业务场景和项目需求。

http://www.xdnf.cn/news/197947.html

相关文章:

  • 【quantity】3 Unit 物理量计算库(quantity.rs)
  • c语言的指针详解
  • js补环境工具使用技巧、补环境实例、重点环境检测点详解
  • Qt开发:XML文件的写入与读取
  • AI与机器人外科手术:如何用智能化技术提升手术精度与安全性?
  • 【android bluetooth 协议分析 06】【l2cap详解 10】【通过avdtp连接流程,感受l2cap通道的生命周期变化】
  • [JavaScript]对象关联风格与行为委托模式
  • WSL释放空间
  • ‌wangEditor 所有菜单项分类、说明及隐藏方法
  • Java项目场景题深度解析
  • Termux - Android终端应用与Linux环境
  • Java读Excel:解析阿里云easyExcel导入文件的行号
  • vmare pro安装报错用户在命令行上发出了EULAS_AGREED=1,表示不接受许可协议的错误解决方法
  • 高压开关柜局部放电信号分析系统
  • C/C++链表的常用操作实现
  • three.js后处理原理及源码分析
  • HTML5好看的水果蔬菜在线商城网站源码系列模板7
  • 文档在线协同工具ONLYOFFICE教程:如何使用宏突出显示具有特定提示文本的空文本字段
  • window 图形显示驱动-在 WDDM 1.2 中提供无缝状态转换(下)
  • 系统架构师2025年论文《论面向对象的软件设计——UML 在面向对象软件架构中的应用》
  • leetcode 876. 链表的中间结点
  • Python 实现的运筹优化系统数学建模详解(动态规划模型)
  • 第二阶段:基础加强阶段总体介绍
  • 网络安全怎么入门?快速了解
  • 基于大模型的公安预审办案笔录分析的挑战与应对策略-3
  • 2025汽车制造企业数字化转型路径参考
  • TypeScript之基础知识
  • vue报错:Loading chunk * failed,vue-router懒加载出错问题。
  • C++复习补充 类型转换和RTTI
  • 人工智能与机器学习:Python从零实现K-Means 算法