Asp.Net6.0学习笔记

5 篇文章 1 订阅
3 篇文章 1 订阅

1.项目

1.1创建

  1. 打开VS,选择新建项目,选择Asp.Net Core 空或Web应用,点击下一步;
    在这里插入图片描述

  2. 配置项目名称、路径等信息,下一步;
    配置新项目

  3. 选择框架版本,将身份验证类型设为无,取消配置HTTPS(H),创建
    在这里插入图片描述

1.2启动

1.2.1VS启动

1.2.2控制台启动

  1. 打开项目路径bin->debug->net6.0(具体.net版本)文件夹,在地址栏中输入cmd;

  2. 打开控制台窗口,输入命令;
    命令有两个:

    1. 默认端口:
      dotnet AspNetCore6.PracticalDemo.dll
      
    2. 指定端口:
      dotnet AspNetCore6.PracticalDemo.dll --urls="http://*:5177";
      dotnet AspNetCore6.PracticalDemo.dll --urls=http://localhost:5177--port=5177
      
  • 说明:
    AspNetCore6.PracticalDemo.dll:项目生成的dll文件;
    5177:访问的端口号

1.3发布

1.3.1IIS

  • 右键项目->发布->选择文件夹;
    发布文件夹

  • 打卡IIS->网站->添加网站,输入指定内容,点击确定;其中物理路径为项目发布路径;
    添加网站

  • ※注意事项:

    发布后如果无法访问需要先安装对应的SDK和Hosting Bundle,安装后在控制面板会有对应的Service安装程序,IIS中的模块会新增AspNetCoreModuleV2模块。
    在这里插入图片描述

2.MVC

2.2视图

2.2.1布局视图

类似与模板,可包含其他视图;

2.2.1.1使用
  1. 新建布局视图
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <div>
        @RenderBody()
    </div>
</body>
</html>
  1. 删除子页面中包含之外的内容;
  2. 标记子页面所使用的布局页;
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "学生详细信息";
}
<div>
    姓名:@Model.Student.Name
</div>
<div>
    邮箱:@Model.Student.Emial
</div>
<div>
    班级名称:@Model.Student.ClassName
</div>
2.2.1.2Section使用
  1. 在布局页定义RenderSection;
@RenderSection("Scripts",false)
  1. 在子页面定义具体的引用。
@section Scripts{ 
    <script src="~/js/MyScript.js"></script>
}
@section 后的Scripts必须与@RenderSection中的参数Scripts命名一致

2.2.2视图开始

视图开始的意义在于将子页面中的公共部分抽离到开始视图中,如子页面引用布局视图的代码,开始视图遵循就近原则,子页面会优先加载离自己最近的开始视图。

@{
    Layout = "_Layout";
}

2.2.3视图导入

视图导入用于导入子页面公共命名空间以及其他指令,视图导入遵循就近原则,子页面会优先加载离自己最近的开始视图。

@using StudentManagement.Models
@using StudentManagement.ViewModels

2.3路由

MVC中路由有两种:常规路由和属性路由;

  1. 常规路由
    默认使用app.UseMvcWithDefaultRoute()添加路由规则:Home/Index/1;
    可以手动配置为自己所需要的路由规则:
app.UseMvc(route => {
     route.MapRoute("Default", "{Controller=Home}/{Action=Index}/{id?}");
});

Core3.1及之后版本:

app.UseRouting();
app.UseEndpoints(routes =>
            {
                routes.MapControllerRoute("default",
                   pattern: "{controller=Home}/{action=Index}/{id?}");
            });
  1. 属性路由

2.4文件上传

  1. 在视图页添加上传文件控件;
@model StudentCreateViewModel
<form enctype="multipart/form-data" asp-controller="home" asp-action="create" method="post" class="mt-3">
    <div class="form-group row mt-3">
        <label asp-for="Photo" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <div class="custom-file">
                <input asp-for="Photo" class="custom-control custom-file-input" />
            </div>
        </div>
    </div>
    <div class="form-group row">
        <div class="col-sm-10">
            <button type="submit" class="btn btn-primary">创建</button>
        </div>
    </div>
</form>
  1. 在控制器中处理将图片文件保存到指定路径;
public IActionResult Create(StudentCreateViewModel model)
        {
            if (ModelState.IsValid)
            {
                string uniqueFileName = null;
                if (model.Photo != null)
                {
                    // wwwroot\images路径
                    string uploadFile = Path.Combine(_hostingEnvironment.WebRootPath, "images");
                    //生成图片唯一值
                    uniqueFileName = Guid.NewGuid() + "_" + model.Photo.FileName;
                    //新文件全路径
                    string newFileName = Path.Combine(uploadFile, uniqueFileName);
                    //将图片复制到新文件中
                    using(FileStream stream=new FileStream(newFileName, FileMode.Create))
                    {
                        model.Photo.CopyTo(stream);
                    }

                    Student newStudent = new Student
                    {
                        Name = model.Name,
                        Email = model.Email,
                        ClassName = model.ClassName,
                        PhotoPath = uniqueFileName
                    };
                    _studentRepository.Add(newStudent);
                    return RedirectToAction("Details", new { id = newStudent.Id });
                }
            }
            return View();
        }
  1. 如果上传图片后,进程退出则按以下步骤设置即可;
    a) 打开工具-选项-项目和解决方案
    b) 选择web项目,将浏览器窗口关闭时停止调试程序,在调试停止时关闭浏览器取消选中;

3 中间件

3.1 静态文件

app.UseStaticFiles();

3.2 默认文件

  1. 使用默认文件
app.UseDefaultFiles();
  1. 修改默认文件
DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions();
defaultFilesOptions.DefaultFileNames.Clear();
defaultFilesOptions.DefaultFileNames.Add("MyPage.html");
app.UseDefaultFiles(defaultFilesOptions);

3.3 404找不到页面

3.3.1 添加中间件

当找不到路由时,加载默认错误页面

app. UseStatusCodePages();
3.3.2重定向
  1. UseStatusCodePagesWithRedirects
    找不到路由时重定向到指定的路由,该中间件会覆盖原始请求路径;
app. UseStatusCodePagesWithRedirects ("/Error/{0}");
  1. UseStatusCodePagesWithReExecute
    找不到路由时重定向到指定的路由,该中间件不会覆盖原始请求路径,建议使用该中间件;
app. UseStatusCodePagesWithReExecute ("/Error/{0}");
3.3.3 添加Error控制器及方法
public class ErrorController: Controller
{
[Route("/Error/{statusCode}")]
        public IActionResult HttpStatusCodeHandler(int statusCode)
        {
            switch (statusCode)
            {
                case 404:
                    ViewBag.ErrorMessage = "抱歉,你访问的页面不存在";
                    break;
            }
            return View("NotFound");
}
}
3.3.4添加404页

3.4错误页面

当发生异常时会跳转到指定error视图中。

  1. 添加UseExceptionHandler中间件
app.UseExceptionHandler("/Error");
  1. 添加Error控制器及方法
public class ErrorController: Controller
{
[AllowAnonymous]//允许匿名访问(即不需要登录也可以访问)
        [Route("Error")]
public IActionResult Error()
{
var exceptionHandle=  HttpContext.Features.Get<IExceptionHandlerPathFeature>();
ViewBag.ExceptionPath = exceptionHandle.Path;//异常路径
ViewBag.ErrorMessage= exceptionHandle.Error.Message;// 异常信息
ViewBag.ErrorStackTrace= exceptionHandle.Error.StackTrace;// 异常堆栈
    	return View();
}
}

3.添加具体Error页面

注入服务

  1. 中文乱码
builder.Services.AddControllersWithViews().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
});
  1. Session
builder.Services.AddSession();

工具

客户端工具LibMan

轻量级的客户端管理工具,可以从CND下载客户端和框架;
注:必须在VS2017版本15.8及以上可以使用。

安装Bootstrap

  1. 右键wwwroot文件夹,选择新建-客户端;
    新建客户端
  2. 打开添加客户端窗口,输入twitter-bootstrap,安装;
    选择bootstrap版本
  3. 等待下载完成即可。

TagHelper

引入

在视图中引入TagHelper:
@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers

使用

  1. asp-controller:控制器名
  2. asp-action:方法名
  3. asp-route-id:参数
  4. asp-append-version
    属性设置为true时,会为图片标记一个特有的hash值,作用是当本机的值变化时才从服务器中重新读取图片。
  5. asp-for
<label asp-for="Name"> </label>
默认会生成Id=Name,Name=Name,该Name为Model中的具体属性;
  1. asp-items
asp-items="Html.GetEnumSelectList<ClassNameEnum>()"
用于生成ClassNameEnum类型的的选择项;
  1. asp-validation-summary
    用于模型验证,值分别为All、ModelOnly和None;

注解

HttpGet和HttpPost

该注解用于请求时设置请求方法为Get或者Post方式,当一个控制器中有两个同名方法,但请求方式不同时则用该注解,默认为HttpGet。
[HttpGet]
public IActionResult Create()
{
    return View();
}
[HttpPost]
public RedirectToActionResult Create(Student student)
{
     _studentRepository.Add(student);
     return RedirectToAction("Details",new { id = student.Id });
}

Required

用于模型验证。

依赖注入

注入实例

Singleton

注入Singleton

services.AddSingleton<IStudentRepository, SQLStudentRepository>();

Scoped

在这里插入图片描述

 services.AddScoped<IStudentRepository, SQLStudentRepository>();

Transient

在这里插入图片描述

services.AddTransient<IStudentRepository, SQLStudentRepository>();

热更新

当cshtml页更改后实时更新网站中的内容而不用重新启动项目;

services.AddMvc().AddRazorOptions(options => options.AllowRecompilingViewsOnFileChange = true);

EF Core

SqlServer

使用

  1. 右键项目,选择Nuget管理,搜索Microsoft.EntityFrameworkCore.SqlServer;

  2. 选择指定的版本,安装;

  3. 新建Context类继承DbContext;

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

        }
        public DbSet<Student> Students { get; set; }//模型对应表文件
}

对于该类中使用的每个实体都需要添加DbSet 属性,将此属性查询和保存TEntity的实例
4. 连接SqlServer

//注入DbContext
services.AddDbContextPool<AppDbContext>(
                options => options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=MyDB-2;Trusted_Connection=True")
) ;

Trusted_Connection=True表示使用Windows认证。
连接字符串建议存放在appsettings.json或其他配置文件中,使用如下

services.AddDbContextPool<AppDbContext>(
                options => options.UseSqlServer(Configuration.GetConnectionString("StudentDBConnection"))
                ) ;

该服务必须在builder.Build()之前注册,否则会报错
在appsetting.json文件中添加以下连接字符串

"ConnectionStrings": {
    "StudentDBConnection": "Server=(localdb)\\mssqllocaldb;Database=StudentDB;Trusted_Connection=True"
    //连接本地数据库
    BlogDBConnection": "Data Source=DESKTOP-EK117L1\\MYSQLSERVER;Database=MyBlog;uid=sa;pwd=123456;Encrypt=True;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=true"
  }

数据库迁移

  1. get-help about_entityframeworkcore
    使用该命令获取命令帮助。

  2. Add-Migration
    使用该命令添加数据库迁移(默认执行最新的迁移文件),输入Name(迁移名称,自定义) ,命令执行成功后会在项目中生成快照。

  3. update-database
    更新到数据库;
    在这里插入图片描述

  4. 删除已更新至数据库的内容

在这里插入图片描述

添加种子数据

  1. 重写DbContext中的OnModelCreating方法;
 protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>().HasData(
                new Student
                {
                    Id = 1,
                    Name = "孙悟空",
                    ClassName = ClassNameEnum.FirstGrade,
                    Email = "wukong@163.com"
                }
            );
        }
  1. 在Nugget控制台中执行add-Migration seedStudentsTabls命令,seedStudentsTabls为自定义名称,用于表示当前迁移的作用名称
  2. 在Nugget控制台中执行update-database命令,更新数据库数据。

数据操作

新增
public Student Add(Student student)
        {
            _dbContext.Students.Add(student);
            _dbContext.SaveChanges();
            return student;
        }
删除
public Student Delete(int id)
        {
            var student=_dbContext.Students.Find(id);
            if (student != null)
                _dbContext.Students.Remove(student);
            return student;
        }
修改
public Student Update(Student uStudent)
        {
            var stu = _dbContext.Students.Attach(uStudent); ;
            stu.State = Microsoft.EntityFrameworkCore.EntityState.Modified;
            _dbContext.SaveChanges();
            return uStudent;
        }
查询
public IEnumerable<Student> GetAllStudents()
        {
            return _dbContext.Students;
        }

日志

ILogger

使用步骤

  1. 在需要使用日志的地方注入ILogger;
    在Error控制器中注入ILogger接口;
public class ErrorController: Controller
    {
        private ILogger<ErrorController> _logger;
        public ErrorController(ILogger<ErrorController> logger)
        {
            _logger = logger;
        }
}
  1. 写日志;
    在指定方法中写入日志
[Route("Error")]
public IActionResult Error()
{
_logger.LogError("发生了一个异常,请检查!"); 
return View();
}

Nlog

使用步骤

  1. 打开NuGet扩展工具,搜索NLog.Web.AspNetCore,选择需要的版本点击安装;
    在这里插入图片描述

  2. 新建nlog.config文件;

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<!-- 要写入的目标内容 -->
	<targets>
		<!-- 将日志写入文件的具体位置  -->
		<target name="allfile" xsi:type="File"
				fileName="D:\Cache\StudentManagement\Logs\nlog-all-${shortdate}.log"/>
	</targets>
	<!-- 将日志程序名称映射到目标的规则 -->
	<rules>
		<!--记录所有日志,包括Microsoft级别-->
		<logger name="*" minlevel="Information" writeTo="allfile" />
	</rules>
</nlog>
  1. 在Program.cs中注册NLog;
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args).ConfigureLogging(
                (hostingContext, logging) =>{
//覆盖原有的日志记录启用NLog
 logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                    logging.AddConsole();
                    logging.AddDebug();
                    logging.AddEventSourceLogger();
                    //启动NLog作为记录日志的程序之一
                    logging.AddNLog();
                })
            .UseStartup<Startup>();
  1. 注入ILogger接口
public class ErrorController: Controller
    {
        private ILogger<ErrorController> _logger;
        public ErrorController(ILogger<ErrorController> logger)
        {
            _logger = logger;
        }
}
  1. 写日志
_logger.LogInformation("这是NLogger信息日志");

AOP-Filter

共包含六种:权限验证、资源缓存、方法前后的记录、结果生成前后扩展、响应结果的补充、异常处理

权限验证

角色授权

  1. 配置鉴权和授权
builder.Services.AddAuthentication(option =>
{
    option.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;//Cookie方式
    option.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultForbidScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,option=> {
	//如果未找到用户Cookie,鉴权失败,跳转至指定Action中
    option.LoginPath = "/Account/Login";
    //如果用户登录成功,但是角色没有指定权限则跳转至该Action中
    option.AccessDeniedPath = "/Error/NoAuthority";
});
  1. 添加鉴权和授权中间件
app.UseAuthentication();//鉴权
app.UseAuthorization();//授权
如果路由配置app.UseRouting()和app.UseEndpoints(...)同时存在,则该中间件必须放在app.UseRouting()和app.UseEndpoints(...)之间,否则会报错
  1. 标记授权的Action
//Authorize:表示用户必须登录
//Roles= "Admin":标记用户角色必须为Admin时才可以访问
[Authorize(AuthenticationSchemes= CookieAuthenticationDefaults.AuthenticationScheme, Roles= "Admin")]
public IActionResult Index(){
	return View();
 }
  1. 鉴权不通过跳转的指定Action
		[HttpPost]
        public async Task<IActionResult> Login(User model)
        {
            if (ModelState.IsValid)
            {
                if (model.Name == "chongzi" && model.Password == "1")
                {
                	//以下Claim可以写入任意数据
                    var claims = new List<Claim>()//用于鉴别当前用户相关信息
                    {
                        new Claim("Userid","1"),
                        new Claim(ClaimTypes.Role,"Admin"),//标记该用户角色为Admin
                        new Claim(ClaimTypes.Name,$"{model.Name}-来自于Cookies'"),//标记该用户名
                        new Claim(ClaimTypes.Email,$"18829206496@163.com"),//标记该用户邮箱
                        new Claim("password",model.Password),
                        new Claim("Account","Administrator"),
                        new Claim("role","admin")
                    };
                    ClaimsPrincipal userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Customer"));
                    HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userPrincipal, new AuthenticationProperties
                    {
                        ExpiresUtc = DateTime.UtcNow.AddMinutes(1)//过期时间为1分钟
                    }).Wait();
                    var user = HttpContext.User;
                    return base.Redirect("/Home/Index");
                }
            }
            return View();
        }
  1. 如果登录成功,但是角色不匹配则跳转至AccessDeniedPath 指定的路径

注意事项

  1. 当同时标记多个Authorize时,若有多个角色Role,则用户必须同时拥有指定角色,才可以正常访问;
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme, Roles = "Admin")]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme, Roles = "Teacher")]
  1. 当只标记一个Authorize时,用户只需满足其中某一个角色都可以正常访问。
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme, Roles = "Admin,Teacher")]

策略授权

  1. 添加策略
builder.Services.AddAuthorization(option =>
{
	//定义名为MyPolicy的策略
    option.AddPolicy("MyPolicy", policy =>
    {
        policy.RequireRole("Admin,User,Teacher");//验证角色必须包含Admin或User或Teacher
        policy.RequireUserName("chongzi1");//验证角色名字必须为chognzi
        policy.RequireAssertion(handler =>//可添加不同逻辑
        {
            return handler.User.HasClaim(c => c.Type == ClaimTypes.Role);//是否存在角色
        });
    });
});
  1. 在Action中标注
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme,Policy = "MyPolicy")]
public IActionResult Index44()
{
	return new JsonResult("/Home/Index4 View");
}

数据库或其他第三方授权

  1. 添加服务接口
public interface IUserService
{
	bool Validata(string id, string qq);
}
  1. 定义类实现服务接口
public class UserService : IUserService
    {
        public bool Validata(string id, string qq)
        {
        	//各种业务逻辑验证,如数据库、QQ、微信或其他第三方
            return true;
        }
    }
  1. 定义Requirement类并实现IAuthorizationRequirement接口
public class QQEmailRequirement: IAuthorizationRequirement
{
}
  1. 定义Handler类实现AuthorizationHandler
public class QQHandler : AuthorizationHandler<QQEmailRequirement>
{
        private IUserService _UserService;
        public QQHandler(IUserService userService)
        {
            _UserService = userService;
        }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, QQEmailRequirement requirement)
        {
            string id = context.User.Claims.First(c => c.Type == "Userid").Value;
            string qq = context.User.Claims.First(c => c.Type == "QQ").Value;
            if(_UserService.Validata(id, qq))
            {
                context.Succeed(requirement); 
            }
            return Task.CompletedTask;
        }
}
  1. 注入需要的依赖
builder.Services.AddTransient<IUserService, UserService>();
builder.Services.AddTransient<IAuthorizationHandler, QQHandler>(); 
  1. 添加策略授权
builder.Services.AddAuthorization(option =>
{
    option.AddPolicy("MyPolicy", policy =>
    {
        policy.AddRequirements(new QQEmailRequirement());
    });
});

资源缓存

主要用于做缓存服务。

IResourceFilter

流程
  1. 自定义ResourceFilte类继承Attribute并实现IResourceFilter接口
public class MyResourceFilterAttribute : Attribute, IResourceFilter
{
	//用于存储缓存内容
	private static Dictionary<string, object> _DicCache = new Dictionary<string, object>();
	//在访问资源之前调用
	public void OnResourceExecuting(ResourceExecutingContext context)
	{
		string key = context.HttpContext.Request.Path;//当前请求路径
		if(_DicCache.ContainsKey(key) )
		{	
			//如果执行到此处,则直接返回到调用的地方,不会往后执行
			context.Result =(IActionResult)_DicCache[key];
		}
		Console.WriteLine("Exceuted MyResourceFilterAttribute.OnResourceExecuting");
 	}
	 //在访问资源之后调用
	public void OnResourceExecuted(ResourceExecutedContext context)
	{
		string key = context.HttpContext.Request.Path;//当前请求路径
        _DicCache[key]= context.Result;
 		Console.WriteLine("Exceuted MyResourceFilterAttribute.OnResourceExecuted");
	}

}
  1. 在指定Action中标注该特性
public class ResourceController: Controller
    {
        public ResourceController()
        {
            Console.WriteLine("ResourceController被构造了");
        }
        [MyResourceFilter]
        public IActionResult Index()
        {
            Console.WriteLine("Exceuted ResourceController.Index");
            return new JsonResult(new[] { "你好呀", "虫子不吃鸟" });
        }
    }
执行顺序
  1. MyResourceFilterAttribute.OnResourceExecuting();
  2. ResourceController构造方法;
  3. 指定Action:Index;
  4. MyResourceFilterAttribute.OnResourceExecuted();

IAsynResourceFilter

异步缓存

流程
  1. 自定义ResourceFilte类继承Attribute并实现IAsyncResourceFilter接口
public class MyAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter
    {
    	//用于存储缓存内容
        private static Dictionary<string, object> _DicCache=new Dictionary<string, object>();
        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            Console.WriteLine("Exceuted MyAsyncResourceFilterAttribute.OnResourceExecutionAsync Before");
            string key = context.HttpContext.Request.Path;//当前请求路径
            if (_DicCache.ContainsKey(key))
            {
            	//如果执行到此处,则直接返回到调用的地方,不会往后执行
                context.Result = (IActionResult)_DicCache[key];
            }
            else
            {
                ResourceExecutedContext resource = await next.Invoke();
                _DicCache[key] = resource.Result;
                Console.WriteLine("Exceuted MyAsyncResourceFilterAttribute.OnResourceExecutionAsync After");
            }
        }
    }
  1. 在指定Action中标注该特性
public class ResourceController : Controller
    {
        public ResourceController()
        {
            Console.WriteLine("ResourceController被构造了");
        }
        [MyAsyncResourceFilter]
        public IActionResult Index()
        {
            Console.WriteLine("Exceuted ResourceController.Index");
            return new JsonResult(new[] { "你好呀", "虫子不吃鸟" });
        }
    }
执行顺序
  1. await next.Invoke()执行之前
  2. ResourceController构造方法;
  3. 指定Action:Index;
  4. await next.Invoke()执行之后

方法前后的记录

结果生成前后扩展

响应结果的补充

异常处理

反向代理

Ninginx

使用步骤

  1. 下载
    Ninginx下载地址

  2. 修改端口号
    默认端口号为80,将其修改为其他值,打开下载路径\conf\nginx.conf文件:
    在Server节点中修改listen的值即可

  3. 转发

    • 单个转发
      server-location节点中添加 :
      proxy_pass http://localhost:9002;
      

    单个转发

    • 多个转发
      1. 添加服务列表,在http节点之中,server节点之前添加以下内容
        	upstream net6WebApi{ 
        		server localhost:9002   weight:1;
        		server localhost:9003;
        		server localhost:9004;
        	}	
        
        net6WebApi:服务列表名称,自定义
        weight:设置该服务器的请求权重,默认为轮询策略
      2. server-location节点中添加:
        proxy_pass http://net6WebApi;
        
  4. 启动
    在nginx.exe所在目录中运行cmd,输入start nginx即可启动

指令

  1. 启动
    start nginx
    
  2. 热加载
    nginx -s reload
    
  3. 停止
    nginx -s quit
    
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ASP.NET 6.0是微软公司发布的一种开发Web应用程序的框架。它是ASP.NET框架的下一个主要版本,并且具有很多新的功能和改进。 ASP.NET 6.0采用了MVC(Model-View-Controller)模式,这是一种用于构建可维护和可扩展的Web应用程序的软件设计模式。 MVC将应用程序分为三个主要的组件:模型(Model)、视图(View)和控制器(Controller)。 模型是应用程序的核心,它包含用于处理数据和业务逻辑的代码。视图是用户界面的表示,负责将数据呈现给用户。控制器是处理用户请求的组件,它接收用户输入并根据输入来处理模型和视图。 ASP.NET 6.0的MVC框架提供了许多功能来简化Web开发。它具有可扩展性和灵活性,可以轻松集成其他技术和工具。它还支持可测试性,使开发人员可以方便地编写单元测试和集成测试。 ASP.NET 6.0还引入了一些新的特性和改进。其中包括原生对Blazor的支持,这是一种使用C#和.NET开发浏览器端应用程序的框架。它还引入了Razor Pages,这是一种用于构建简单Web页面的轻量级模型。此外,ASP.NET 6.0还提供了对gRPC和SignalR等实时通信技术的原生支持。 总而言之,ASP.NET 6.0的MVC框架是一种强大而灵活的工具,用于构建可维护和可扩展的Web应用程序。它提供了丰富的功能和改进,使开发人员能够更轻松地创建高质量的应用程序。无论是小型项目还是大型企业级应用,ASP.NET 6.0都能满足开发人员的需求并提供卓越的性能和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虫子不吃鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值