asp.net core移植
替换方案
Asp. Net Mvc | ASP. NET Core | 说明 |
---|---|---|
FormsAuthenticationTicket | AuthenticationTicket | 参考Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler的HandleSignInAsync方法 |
HttpRuntime.AppDomainAppVirtualPath | 据说已被干掉,用不到 | |
HttpRuntime.AppDomainAppPath | (IHostingEnvironment)Env.ContentRootPath | |
HttpPostedFileBase | IFormFile | |
ActionDescriptor.IsDefined | ControllerActionDescriptor.MethodInfo.IsDefind | ActionDescriptor需要转换成ControllerActionDescriptor |
Request[key] | Request.Form[key] & Request.Query[key] | 需要判断这两个,返回的类型StringValues,而不会是null |
Request.IsAjaxRequest() | Request.Headers[“x-requested-with”]==“XMLHttpRequest” | |
Request.QueryString[key] | Request.Query[key] | |
Request.RawUrl | Request.GetEncodedUrl() | |
Request.RouteData.GetRequiredString() | HttpContext.GetRouteValue() | |
Request.ServerVariables | Request.Headers | |
Request.Url.PathAndQuery | Request.GetEncodedPathAndQuery() | |
Request.UrlReferrer | Request.Headers[HeaderNames.Referer] | |
Request.UserAgent | Request.Headers[HeaderNames.UserAgent] | |
Response.Output | new StreamWriter(HttpContext.Response.Body) | |
System.Runtime.Caching | Microsoft.Extensions.Caching.Memory |
注意
- request.Form有时候是异常,不可读取,可通过
request.HasFormContentType
来判断
路由
- 其中url以及以前defaults参数的默认值可使用template代替,直接指定默认值
- id后一定要加问号,效果等同于
Asp. Net Mvc
的id = UrlParameter.Optional
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
自定义添加路由
- 需要判断路由的默认处理
DefaultHandler
是否为空,否则添加失败
app.UseRouter(routes =>
{
if (routes.DefaultHandler == null) routes.DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>();
// 区域路由注册
routes.MapRoute(
name: "CubeAreas",
template: "{area=Admin}/{controller=Index}/{action=Index}/{id?}"
);
});
区域
- 官方文档
Asp. Net Mvc
中的区域会自动注册本区域文件夹里面的控制器作为区域的控制器,Asp. Net Core Mvc
需要在控制器使用特性[Area("Admin")]
指定区域,如果不指定区域就是和正常控制器一样,即使它位于区域文件夹Asp. Net Core Mvc
一定要进行区域路由注册,否则无法匹配带有Area
特性的控制器- 在没有任何路由注册默认控制器为
Index
的情况下,如果有控制器名为IndexController
,在Asp. Net Mvc
中访问/Admin/
,会匹配此控制器,但在Asp. Net Core Mvc
中需要指定路由默认控制器有Index
才能匹配 - 总的来说,
Asp. Net Core Mvc
什么都要指定都要设置,不能偷懒 - 路由注册示例
app.UseMvc(routes =>
{
//区域路由注册
routes.MapRoute(
name: "areas",
template: "{area:exists}/{controller=Home}/{action=Index}{id?}"
);
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
视图命名空间导入
- 由
web.config
换成_ViewImports.cshtml
,使用@using
http模块到中间件
-
实例,类要求有Invoke方法,并使用IApplicationBuilder.UseMiddleware方法进行注册,中间件都需要在UseMvc之前注册
public class ErrorModule
{
private readonly RequestDelegate _next;
public ErrorModule(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
// Do something with context near the beginning of request processing.
await _next.Invoke(context);
// Clean up.
}
}
public static class ErrorModuleMiddlewareExtensions
{
public static IApplicationBuilder UseErrorModuleMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<ErrorModule>();
}
}
添加http上下文
- ConfigureServices
//添加Http上下文访问器
StaticHttpContextExtensions.AddHttpContextAccessor(services);
- Configure
//配置静态Http上下文访问器
app.UseStaticHttpContext();
Razor视图
- 参考博客
- 分部页替换:
<partial name="_Login_Login"/>
或@Html.PartialAsync("_Login_Login").Result
导入命名空间
Views
文件夹下的_ViewImports.cshtml
RazorOptions
services
.AddMvc()
.AddRazorOptions(opt =>
{
opt.ViewLocationFormats.Clear();
opt.AreaViewLocationFormats.Clear();
opt.ViewLocationFormats.Add("~/Views/{1}/{0}.cshtml");
opt.ViewLocationFormats.Add("~/Views/Shared/{0}.cshtml");
opt.AreaViewLocationFormats.Add("~/Areas/{2}/Views/{1}/{0}.cshtml");
opt.AreaViewLocationFormats.Add("~/Areas/{2}/Views/Shared/{0}.cshtml");
});
视图引擎
- 待补充
模型绑定
IModelBinder
- 官网
- 继承自
Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder
CreateModel
改为BindModelAsync
方法modelType
模型类型bindingContext.ModelType
controllerContext
为bindingContext.ActionContext
- 返回object改成
bindingContext.Result = ModelBindingResult.Success(entity);
return Task.CompletedTask;
- 示例
public class EntityModelBinder:IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var modelType = bindingContext.ModelType;
var controllerContext = bindingContext.ActionContext;
if (modelType.As<IEntity>())
{
var fact = EntityFactory.CreateOperate(modelType);
if (fact != null)
{
bindingContext.Result = ModelBindingResult.Success(fact.Create());
}
}
return Task.CompletedTask;
}
IModelBinderProvider
public class EntityModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context) =>
context.Metadata.ModelType.As<IEntity>() ? new EntityModelBinder() : null;
}
使用
- 放在第一位优先调用
services.AddMvc(opt =>
{
//模型绑定
opt.ModelBinderProviders.Insert(0,new EntityModelBinderProvider());
});
模型绑定注意事项
- 自定义的模型绑定需要自己实现属性填充,框架并不会再为模型填充属性
- 自带的模型绑定是自动注册的,实现了基本类型的绑定,比如数组、字典、枚举、二进制数据,复杂类型绑定绑定过程会根据属性的类型选择上述的绑定器实现属性绑定
过滤器Filter
- 文档
- 注意:
- 过滤器在中间件之后执行
- 异常筛选器在action执行之后执行,仅能捕获mvc流程中action中发生的异常
上传文件(表单内容)大小限制
.UseKestrel(options =>
{
options.Limits.MaxRequestBodySize = null;
}
- 或者
// 设置表单内容限制
services.Configure<FormOptions>(formOptions =>
{
formOptions.ValueLengthLimit = int.MaxValue; // 表单内容大小限认4194304,单位byte
formOptions.MultipartBodyLengthLimit = int.MaxValue; // multipart,默认134217728
});
数据验证
- 待补充
模型绑定验证
- 待补充
响应流写入、设置、推送
- 待补充
登录授权
总结
- 只管迁移,没有较大的问题,部分需要注意的是一些用法变革,不再支持,做着有新的方式替代,重新实现就好(不过很少遇到)。