asp.net core移植
[TOC]
替换方案
Asp. Net Mvc |
ASP. NET Core |
说明 |
HttpRuntime.AppDomainAppVirtualPath |
|
据说已被干掉,用不到 |
HttpRuntime.AppDomainAppPath |
(IHostingEnvironment)Env.ContentRootPath |
|
HttpPostedFileBase |
IFormFile |
|
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 |
ASP.NET Core中没有ServerVariables的对应实现,有的可以在HttpContext.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根据请求类型决定该参数是否可以正常读取
路由
- 其中url以及以前defaults参数的默认值可使用template代替,直接指定默认值
- id后一定要加问号,效果等同于
Asp. Net Mvc
的id = UrlParameter.Optional
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
区域
- 官方文档
Asp. Net Mvc
中的区域会自动注册本区域文件夹里面的控制器作为区域的控制器, Asp. Net Core Mvc
需要在控制器使用特性[AdminArea]
指定区域,如果不指定区域就是和正常控制器一样,即使它位于区域文件夹
Asp. Net Core Mvc
一定要进行区域路由注册,否则无法匹配带有Area
特性的控制器
- 在没有任何路由注册默认控制器为
Index
的情况下,如果有控制器名为IndexController
,在Asp. Net Mvc
中访问/Admin/
,会匹配此控制器,但在Asp. Net Core Mvc
中需要指定路由默认控制器有Index
才能匹配
- 总的来说,
Asp. Net Core Mvc
什么都要指定都要设置,不能偷懒
- 路由注册示例
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"CubeAreas",
"{area=Admin}/{controller=Index}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
.Build();
视图命名空间导入
- 由
web.config
换成_ViewImports.cshtml
,使用@using
http模块到中间件
添加http上下文
//添加Http上下文访问器
StaticHttpContextExtensions.AddHttpContextAccessor(services);
//配置静态Http上下文访问器
app.UseStaticHttpContext();
Razor视图
- 参考博客
- 分部页替换:
<partial name="_Login_Login"/>
或@await Html.PartialAsync("_Login_Login")
导入命名空间
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.CreateFactory(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());
});
过滤器
上传文件大小限制
.UseKestrel(options =>
{
options.Limits.MaxRequestBodySize = null;
}
数据验证
模型绑定验证
响应流写入、设置、推送
登录授权