Net Core 2.X和Net 4.X的功能升级迁移和Bug处理笔记
最近在迁移一些Net 4.X的项目到Net Core 2.X上, 遇到一些代码层面调用方法和类库的修改,这里记录一些我遇到并比较常用的功能点。备查。
其实一些问题stackoverflow上都有解答。算是中文搬运吧(手动滑稽,护住狗头)
PS:MVC 生命周期,EF Core 文档 MVC防伪
https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/lifecycle-of-an-aspnet-mvc-5-application
https://docs.microsoft.com/en-us/ef/core/what-is-new/roadmap
https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-2.1
通用:
Q:App.Cinfig或Web.Config的ConnectionString或AppSetting读取:
在Net 4.X下我们可以直接通过ConfigurationManager访问到Web.Config或App.Config里的配置项。
string connstr = ConfigurationManager.ConnectionStrings["name"].ConnectionString;
string appvalue = ConfigurationManager.AppSettings["RedisPassword"];
其实在Net Core 2.X里同样是可以访问到的,只需要安装NuGet包 :System.Configuration.ConfigurationManager 就OK.(VS默认的开发模版并未依赖)
Q:Sql Server Geometry类型 Model 反射问题:
note:EF Core 2.2已经完善解决方式并解决/可视情况更新: https://docs.microsoft.com/zh-cn/ef/core/modeling/spatial
在Net 4.X框架里,集成了Geometry类型.所以用一些ORM转换SQL 为dynamic 时,可以通过。但是net core 2.x暂时没有集成,需要在T-Sql里对 几何类型调用 ToString() 转换
MVC/WEBAPI相关:
Q.Net Core 和 Net 4.X 的 Route 和 Area相关:
Net Core里已经不再区分WebAPI和MVC控制器和路由注册,Area的路由注册也集中到了Configure的UseMvc中注册,不再像Net4.x再Area目录里配置
Note:需要注意的是在Net4.X中,在调用RouteMap时配置 namespaces防止Area控制器与Controller目录重名的问题.
而NetCore中,已经移除了namespaces 参数则是AreaAttribute特性进行约束:
[Area("TestArea")] public class HomeController : Controller { public IActionResult Index() { return View(); } }
例子:
Net4.X:
以RouteConfig.cs文件为例:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, namespaces: new string[] { "WebApplication2.Controllers" } ); } }
Net Core 2.X:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {try { #region 其他常用配置
#endregion #region MVC 和WebAPI 相关 app.UseMvc(routes => { // MVC routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); // WebAPI routes.MapRoute("WebAPI", "api/{controller=Test}/{action=HelloNetCore}/{id?}"); // Area routes.MapAreaRoute(name: "TestArea", areaName:"TestArea",template: "TestArea/{controller}/{action}"); }); #endregion } catch (Exception ex) { } }
Q.Net Core 和Net 4.X 的Cookie:
Net4.X的Cookie是一个HTTPCookie类,现在的话Net Core 直接是个字符串数组了。
最加Net Core 2.1后,默认不允许使用Cookie了,理由和决解方案:
https://www.cnblogs.com/GuZhenYin/p/9154447.html
获取:
Net4.X
HttpCookie cookie = HttpContext.Current.Request.Cookies["key"];
Net Core 2.X
string cookie = HttpContext.Request.Cookies["key"];
删除(PS:删除Cookie的最佳方式是设置Cookie过期):
Net 4.X
HttpContext.Current.Response.Cookies.Remove("key");
Net Core 2.X:
HttpContext.Response.Cookies.Delete("key");
创建:
Net4.X:
var cookie = new HttpCookie("key", "value") { HttpOnly = true, Secure = FormsAuthentication.RequireSSL, Path = "/", Expires = DateTime.Now.AddYears(10) }; HttpContext.Current.Response.Cookies.Add(cookie);
Net Core 2.X:
HttpContext.Response .Cookies .Append("key", "value", new CookieOptions { HttpOnly = true, Secure = true, Path = "/", Expires = DateTime.Now.AddYears(10) });
Q:静态文件包相关:
Net 4.X的JS和CSS的插件(Jquery和Bootstrap之类)一般都是直接包含引用或通过NuGet包安装/在Config里配置,维护管理成本其实很高。
然后Net Core里不在推荐使用以前的前端依赖管理.
静态类的文件推荐使用Bower/npm/yarn进行前端依赖的安装管理。虽然加大的学习成本。但是面对现在日益庞大的前端功能。这种管理静态文件的方式转变还是很有必要的。
以为例:
Bower在MVC Core 中的使用:
首先确认电脑安装好Node.js(当前稳定版本8.9.X)
然后安装Bower 这里是全局安装
npm install -g bower
用VS 2017创建一个空的MVC项目,并Init Bower.在MVC项目根目录,用命令行,并根据步骤填写相关信息:
bower init
然后手动在MVC项目目录下创建一个.bowerrc 文件。
并把如下配置复制到文件里。然后工程就算建好了。
{ "directory": "wwwroot/lib" }
在bower.json里。我们可以根据自己的需要安装相关的Package包
然后通过
bower init
命令 进行安装
Q.IHttpModule和IHttpHandler在MVC中的实现:
Net Core把IHttpModule和IHttpHandler都整合到了中间件.文档阐述的比较详细,就不贴栗子了.
文档: https://docs.microsoft.com/en-us/aspnet/core/migration/http-modules?view=aspnetcore-2.1
Q.ActionFilterAttribute过滤器 访问Controller :
wait edit
Q.Controller Request和Response 获取Url:
wait edit
Q.MVC/WebAPI:Antiforgery防伪 (防XSRF/CSRF攻击):
防伪的变化不是很大,以前是过滤器,现在改成了注入中间件
扩展阅读:https://odetocode.com/blogs/scott/archive/2017/02/06/anti-forgery-tokens-and-asp-net-core-apis.aspx
#region 页面防伪 services.AddAntiforgery(opt => { opt.Cookie.Name = "QING-ANTIFORGERY-TOKEN"; opt.HeaderName = "QING-X-ANTIFORGERY-TOKEN"; opt.Cookie.SecurePolicy = CookieSecurePolicy.None; opt.Cookie.HttpOnly = false; opt.SuppressXFrameOptionsHeader = false; }); #endregion
app.Use(next => context => {var tokens = antiforgery.GetAndStoreTokens(context); context.Response.Cookies.Append("QING-X-ANTIFORGERY-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false }); return next(context); });
function getCookie(cname) { var name = cname + "="; var decodedCookie = decodeURIComponent(document.cookie); var ca = decodedCookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') { c = c.substring(1); } if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); } } return ""; } var csrfToken = getCookie("QING-X-ANTIFORGERY-TOKEN"); console.log(csrfToken); var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function () { if (xhttp.readyState == XMLHttpRequest.DONE) { if (xhttp.status == 200) { alert(xhttp.responseText); } else { alert('There was an error processing the AJAX request.'); } } }; xhttp.open('POST', '/home/test', true); xhttp.setRequestHeader("Content-type", "application/json"); xhttp.setRequestHeader("QING-X-ANTIFORGERY-TOKEN", csrfToken); xhttp.send();
Q.MVC/WebAPI:WebSocket支持示例:
Net Core :
一对一:
Q.MVC/WebAPI:SignalR支持示例:
wait