NET Framework項目移植到NET Core上遇到的一系列坑(2)

目錄html

  1. 獲取請求的參數
  2. 獲取完整的請求路徑
  3. 獲取域名
  4. 編碼
  5. 文件上傳的保存方法
  6. 獲取物理路徑
  7. 返回Json屬性大小寫問題
  8. webconfig的配置移植到appsettings.json
  9. 設置區域塊MVC的路由器和訪問區域塊的視圖
  10. NetCore訪問靜態資源文件
  11. MVC調用子頁視圖
  12. 過濾器
  13. 使用session和解決sessionID一直變化的問題
  14. MD5加密
  15. Path.Combine()
  16. DateTime

1.獲取請求的參數

NET Framework版本:web

1 Request["xxx"];
2 Request.Files[0];

NET Core版本:json

1 Request.Form["xxx"];
2 Request.Form.Files[0];

2.獲取完整的請求路徑

NET Framework版本:session

1 Request.RequestUri.ToString(); 

NET Core版本:app

1 //先添加引用
2  
3 using Microsoft.AspNetCore.Http.Extensions;
4  
5 //再調用
6 Request.GetDisplayUrl();

 

3.獲取域名

NET Framework版本:async

1 HttpContext.Current.Request.Url.Authority

NET Core版本:ide

1 HttpContext.Request.Host.Value

4.編碼

NET Framework版本:svg

1 System.Web.HttpContext.Current.Server.UrlEncode("<li class=\"test\"></li>")
2 "%3cli+class%3d%22test%22%3e%3c%2fli%3e"
3 System.Web.HttpContext.Current.Server.UrlDecode("%3cli+class%3d%22test%22%3e%3c%2fli%3e")
4 "<li class=\"test\"></li>"

NET Core版本:函數

 1 //兩種方法,建議用System.Web.HttpUtility
 2 System.Web.HttpUtility.UrlEncode("<li class=\"test\"></li>");
 3 "%3cli+class%3d%22test%22%3e%3c%2fli%3e"
 4 System.Web.HttpUtility.UrlDecode("%3cli+class%3d%22test%22%3e%3c%2fli%3e");
 5 "<li class=\"test\"></li>"
 6  
 7 System.Net.WebUtility.UrlEncode("<li class=\"test\"></li>")
 8 "%3Cli+class%3D%22test%22%3E%3C%2Fli%3E"
 9 System.Net.WebUtility.UrlDecode("%3Cli+class%3D%22test%22%3E%3C%2Fli%3E")
10 "<li class=\"test\"></li>"
11 System.Net.WebUtility.UrlDecode("%3cli+class%3d%22test%22%3e%3c%2fli%3e")
12 "<li class=\"test\"></li>"

 

 

5.文件上傳的保存方法

NET Framework版本:fetch

1 var file = Request.Files[0];
2  
3 //blockFullPath指保存的物理路徑
4  
5 file.SaveAs(blockFullPath);

NET Core版本:

 1 var file = Request.Form.Files[0];
 2  
 3 //blockFullPath指保存的物理路徑
 4  
 5 using (FileStream fs = new FileStream(blockFullPath, FileMode.CreateNew))
 6  
 7 {
 8  
 9 file.CopyTo(fs);
10  
11 fs.Flush();
12  
13 }

 

 

6.獲取物理路徑

NET Framework版本:

1 //做爲一個全局變量獲取物理路徑的方法
2  
3 public string ffmpegPathc = System.Web.Hosting.HostingEnvironment.MapPath("~/Content/ffmpeg/ffmpeg.exe");
4  
5 //獲取在控制器的構造函數裏直接調用Server.MapPath
6  
7 ffmpegPathc = Server.MapPath("~/Content/ffmpeg/ffmpeg.exe");

NET Core版本:

 1 //從ASP.NET Core RC2開始,能夠經過注入 IHostingEnvironment 服務對象來取得Web根目錄和內容根目錄的物理路徑。代碼以下:
 2 
 3  
 4 [Area("Admin")]
 5  
 6 public class FileUploadController : Controller
 7  
 8 {
 9  
10 private readonly IHostingEnvironment _hostingEnvironment;
11  
12  
13  
14 public string ffmpegPathc = "";//System.Web.Hosting.HostingEnvironment.MapPath("~/Content/ffmpeg/ffmpeg.exe");
15  
16  
17  
18 public FileUploadController(IHostingEnvironment hostingEnvironment)
19  
20 {
21  
22 _hostingEnvironment = hostingEnvironment;
23  
24 ffmpegPathc = _hostingEnvironment.WebRootPath + "/Content/ffmpeg/ffmpeg.exe";
25  
26 }
27  
28 }

 

這樣寫每一個控制器就都要寫一個構造函數,很麻煩,因此能夠把它抽離出來,寫個公共類去調用。代碼以下:

先自定義一個靜態類:

 1 using Microsoft.AspNetCore.Hosting;
 2  
 3 using Microsoft.Extensions.DependencyInjection;
 4  
 5 using System;
 6  
 7  
 8  
 9 namespace GDSMPlateForm
10  
11 {
12  
13 public static class HttpHelper
14  
15 {
16  
17 public static IServiceProvider ServiceProvider { get; set; }
18  
19  
20  
21 public static string GetServerPath(string path)
22  
23 {
24  
25 return ServiceProvider.GetRequiredService<IHostingEnvironment>().WebRootPath + path;
26  
27 }
28  
29 }
30  
31 }

而後 在startup類下的Configure 方法下:

1 HttpHelper.ServiceProvider = app.ApplicationServices;

startup下的ConfigureServices放下注冊方法(這一步必不可少,可是這裏能夠不寫,由於IHostingEnvironment 是微軟默認已經幫你註冊了,若是是本身的服務,那麼必須註冊)。

1 services.AddSingleton<IHostingEnvironment, HostingEnvironment>();

最後獲取物理路徑就能夠這樣直接調用了:

1 public string ffmpegPathc = HttpHelper.GetServerPath("/Content/ffmpeg/ffmpeg.exe");

 

7.返回Json屬性大小寫問題

NET Core返回Json屬性默認都會自動轉爲小寫,但項目以前Json屬性有些是大寫的,因此須要配置成不轉化爲小寫的形式。

Startup.cs的ConfigureServices方法下添加一行代碼:

1 //Startup須要添加引用
2  
3 using Newtonsoft.Json.Serialization;
4  
5 //返回Json屬性默認大小寫
6  
7 services.AddMvc().AddJsonOptions(o => { o.SerializerSettings.ContractResolver = new DefaultContractResolver(); });

 

8.webconfig的配置移植到appsettings.json

NET Framework版本:

直接能夠讀取webconfig配置文件:

string format = System.Configuration.ConfigurationManager.AppSettings["format"].ToString();

NET Core版本:

NET Core再也不支持web.config,取而代之的是appsettings.json,因此須要把一些配置移植過去。

例如web.config下的一些配置

 1 <appSettings>
 2  
 3 <add key="ismdb" value="" />
 4  
 5 <add key="webpath" value="" />
 6  
 7 <add key="format" value="jpg,jpeg,png,gif,bmp,tif,svg/mp3,wav/mp4,avi,mpg,wmv,mkv,rmvb,mov,flv/zip/.ppt,.pptx" />
 8  
 9 <add key="imagesize" value="5242880" />
10  
11 <!--1024 * 1024 * 5 -->
12  
13 <add key="musicsize" value="20971520" />
14  
15 <!--1024 * 1024 * 20 -->
16  
17 <add key="mediasize" value="20971520" />
18  
19 <!--1024 * 1024 * 20 -->
20  
21 <add key="packagesize" value="0" />
22  
23 <add key="pptsize" value="0" />
24  
25 </appSettings>

移植到appsettings.json

 1 {
 2  
 3 "Logging": {
 4  
 5 "IncludeScopes": false,
 6  
 7 "LogLevel": {
 8  
 9 "Default": "Warning"
10  
11 }
12  
13 },
14  
15 "webpath": "",
16  
17 "format": "jpg,jpeg,png,gif,bmp,tif,svg/mp3,wav/mp4,avi,mpg,wmv,mkv,rmvb,mov,flv/zip/.ppt,.pptx",
18  
19 "imagesize": "5242880",
20  
21 "musicsize": "20971520",
22  
23 "mediasize": "20971520",
24  
25 "packagesize": "0",
26  
27 "pptsize": "0"
28  
29 }

而後編寫一個類去調用這個appsettings.json

 1 using Microsoft.Extensions.Configuration;
 2  
 3 using System.IO;
 4  
 5  
 6  
 7 namespace GDSMPlateForm
 8  
 9 {
10  
11 public class RConfigureManage
12  
13 {
14  
15 public static string GetConfigure(string key)
16  
17 {
18  
19  
20  
21 //添加 json 文件路徑
22  
23 var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");
24  
25 //建立配置根對象
26  
27 var configurationRoot = builder.Build();
28  
29  
30  
31 //取配置根下的 name 部分
32  
33 string secvalue = configurationRoot.GetSection(key).Value;
34  
35 return secvalue;
36  
37 }
38  
39 }
40  
41 }

調用的方式:

1 string format = RConfigureManage.GetConfigure("format");

 

9.設置區域塊MVC的路由器和訪問區域塊的視圖

NET Framework版本:

NET Framework新建一個區域會自帶一個類設置路由器的,如圖:

 

 
 1 using System.Web.Mvc;
 2  
 3  
 4  
 5 namespace GDSMPlateForm.Areas.Admin
 6  
 7 {
 8  
 9 public class AdminAreaRegistration : AreaRegistration
10  
11 {
12  
13 public override string AreaName
14  
15 {
16  
17 get
18  
19 {
20  
21 return "Admin";
22  
23 }
24  
25 }
26  
27  
28  
29 public override void RegisterArea(AreaRegistrationContext context)
30  
31 {
32  
33 context.MapRoute(
34  
35 "Admin_default",
36  
37 "Admin/{controller}/{action}/{id}",
38  
39 new { action = "Index", id = UrlParameter.Optional }
40  
41 );
42  
43 }
44  
45 }
46  
47 }

NET Core版本:

NET Core新建一個區域不會自帶一個類用於設置路由器,因此須要在Startup類的Configure方法裏多加一條路由器設置

 1 app.UseMvc(routes =>
 2  
 3 {
 4  
 5 routes.MapRoute(
 6  
 7 name: "areas",
 8  
 9 template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
10  
11 );
12  
13 });

 

而後須要在每一個控制器下添加一個標籤,指定該控制器屬於哪一個區域的,如圖:

不加的話訪問不到區域的視圖,報404錯誤。

 

10.NetCore訪問靜態資源文件

NET Framework版本:

NET Framework能夠在webconfig下配置這些靜態資源文件

1 <staticContent>
2  
3 <mimeMap fileExtension="." mimeType="image/svg+xml" />
4  
5 <mimeMap fileExtension=".properties" mimeType="application/octet-stream" />
6  
7 </staticContent>

NET Core版本:

NET Core並無webconfig,因此須要在Startup類的Configure方法裏本身配置。

NET Core項目默認的資源文件存在wwwroot下,能夠經過app.UseStaticFiles方法本身定義資源文件的路徑還有類型。

 1 ar provider = new FileExtensionContentTypeProvider();
 2  
 3 provider.Mappings[".properties"] = "application/octet-stream";
 4  
 5 app.UseStaticFiles(new StaticFileOptions
 6  
 7 {
 8  
 9 FileProvider = new PhysicalFileProvider(
10  
11 Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Content")),
12  
13 RequestPath = "/Content",
14  
15 ContentTypeProvider = provider
16  
17 });

 

11.MVC調用子頁視圖

NET Framework版本:

1 @Html.Action("UserBackView", "UserManage")

NET Core版本:

NET Core再也不支持Html.Action(),不過能夠手動本身去實現它。

自定義一個靜態類 HtmlHelperViewExtensions,命名空間設置爲  Microsoft.AspNetCore.Mvc.Rendering。網上找的一個類,複製過來就好了,以下:

  1 using Microsoft.AspNetCore.Html;
  2  
  3 using Microsoft.AspNetCore.Http;
  4  
  5 using Microsoft.AspNetCore.Mvc.Infrastructure;
  6  
  7 using Microsoft.AspNetCore.Routing;
  8  
  9 using Microsoft.Extensions.DependencyInjection;
 10  
 11 using System;
 12  
 13 using System.IO;
 14  
 15 using System.Threading.Tasks;
 16  
 17  
 18  
 19 namespace Microsoft.AspNetCore.Mvc.Rendering
 20  
 21 {
 22  
 23 public static class HtmlHelperViewExtensions
 24  
 25 {
 26  
 27 public static IHtmlContent Action(this IHtmlHelper helper, string action, object parameters = null)
 28  
 29 {
 30  
 31 var controller = (string)helper.ViewContext.RouteData.Values["controller"];
 32  
 33  
 34  
 35 return Action(helper, action, controller, parameters);
 36  
 37 }
 38  
 39  
 40  
 41 public static IHtmlContent Action(this IHtmlHelper helper, string action, string controller, object parameters = null)
 42  
 43 {
 44  
 45 var area = (string)helper.ViewContext.RouteData.Values["area"];
 46  
 47  
 48  
 49 return Action(helper, action, controller, area, parameters);
 50  
 51 }
 52  
 53  
 54  
 55 public static IHtmlContent Action(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
 56  
 57 {
 58  
 59 if (action == null)
 60  
 61 throw new ArgumentNullException("action");
 62  
 63  
 64  
 65 if (controller == null)
 66  
 67 throw new ArgumentNullException("controller");
 68  
 69  
 70  
 71  
 72  
 73 var task = RenderActionAsync(helper, action, controller, area, parameters);
 74  
 75  
 76  
 77 return task.Result;
 78  
 79 }
 80  
 81  
 82  
 83 private static async Task<IHtmlContent> RenderActionAsync(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
 84  
 85 {
 86  
 87 // fetching required services for invocation
 88  
 89 var serviceProvider = helper.ViewContext.HttpContext.RequestServices;
 90  
 91 var actionContextAccessor = helper.ViewContext.HttpContext.RequestServices.GetRequiredService<IActionContextAccessor>();
 92  
 93 var httpContextAccessor = helper.ViewContext.HttpContext.RequestServices.GetRequiredService<IHttpContextAccessor>();
 94  
 95 var actionSelector = serviceProvider.GetRequiredService<IActionSelector>();
 96  
 97  
 98  
 99 // creating new action invocation context
100  
101 var routeData = new RouteData();
102  
103 foreach (var router in helper.ViewContext.RouteData.Routers)
104  
105 {
106  
107 routeData.PushState(router, null, null);
108  
109 }
110  
111 routeData.PushState(null, new RouteValueDictionary(new { controller = controller, action = action, area = area }), null);
112  
113 routeData.PushState(null, new RouteValueDictionary(parameters ?? new { }), null);
114  
115  
116  
117 //get the actiondescriptor
118  
119 RouteContext routeContext = new RouteContext(helper.ViewContext.HttpContext) { RouteData = routeData };
120  
121 var candidates = actionSelector.SelectCandidates(routeContext);
122  
123 var actionDescriptor = actionSelector.SelectBestCandidate(routeContext, candidates);
124  
125  
126  
127 var originalActionContext = actionContextAccessor.ActionContext;
128  
129 var originalhttpContext = httpContextAccessor.HttpContext;
130  
131 try
132  
133 {
134  
135 var newHttpContext = serviceProvider.GetRequiredService<IHttpContextFactory>().Create(helper.ViewContext.HttpContext.Features);
136  
137 if (newHttpContext.Items.ContainsKey(typeof(IUrlHelper)))
138  
139 {
140  
141 newHttpContext.Items.Remove(typeof(IUrlHelper));
142  
143 }
144  
145 newHttpContext.Response.Body = new MemoryStream();
146  
147 var actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor);
148  
149 actionContextAccessor.ActionContext = actionContext;
150  
151 var invoker = serviceProvider.GetRequiredService<IActionInvokerFactory>().CreateInvoker(actionContext);
152  
153 await invoker.InvokeAsync();
154  
155 newHttpContext.Response.Body.Position = 0;
156  
157 using (var reader = new StreamReader(newHttpContext.Response.Body))
158  
159 {
160  
161 return new HtmlString(reader.ReadToEnd());
162  
163 }
164  
165 }
166  
167 catch (Exception ex)
168  
169 {
170  
171 return new HtmlString(ex.Message);
172  
173 }
174  
175 finally
176  
177 {
178  
179 actionContextAccessor.ActionContext = originalActionContext;
180  
181 httpContextAccessor.HttpContext = originalhttpContext;
182  
183 if (helper.ViewContext.HttpContext.Items.ContainsKey(typeof(IUrlHelper)))
184  
185 {
186  
187 helper.ViewContext.HttpContext.Items.Remove(typeof(IUrlHelper));
188  
189 }
190  
191 }
192  
193 }
194  } }

 

而後在Startup中的 ConfigureServices 方法添加:

1 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor();
2  
3 services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

這樣就能夠像NET Framework版本同樣去調用子頁面視圖了:

1 @Html.Action("UserBackView", "UserManage")

 

12.過濾器

NET Framework版本

NET Framework版本上Global.asax中Application_Start方法能夠作不少配置,過濾器也是其中一種。

  1.  
     1 protected void Application_Start()
     2  
     3 {
     4  
     5 AreaRegistration.RegisterAllAreas();
     6  
     7 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);//全局過濾器集合
     8  
     9 RouteConfig.RegisterRoutes(RouteTable.Routes);
    10  
    11 BundleConfig.RegisterBundles(BundleTable.Bundles);
    12  
    13 }
    14  
    15  
    16  
    17 public class FilterConfig
    18  
    19 {
    20  
    21 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    22  
    23 {
    24  
    25 filters.Add(new HandleErrorAttribute());
    26  
    27 filters.Add(new LoginCheckFilterAttribute() { IsCheck = true });//自定義一個過濾器
    28  
    29 }
    30  
    31 }
    32  
    33  
    34  
    35 //繼承過濾器基類並重寫方法
    36  
    37 public class LoginCheckFilterAttribute : ActionFilterAttribute
    38  
    39 {
    40  
    41 //表示是否檢查
    42  
    43 public bool IsCheck { get; set; }
    44  
    45 //Action方法執行以前執行此方法
    46  
    47 public override void OnActionExecuting(ActionExecutingContext filterContext)
    48  
    49 {
    50  
    51 base.OnActionExecuting(filterContext);
    52  
    53 if (IsCheck)
    54  
    55 {
    56  
    57 //添加本身的邏輯
    58  
    59 }
    60  
    61 }
    62  
    63 }

     

NET Core版本:

NET Core不在支持Global.asax,不少配置寫在Startup裏。過濾器的添加方法以下:

 
 1 public void ConfigureServices(IServiceCollection services)
 2  
 3 {
 4  
 5 services.AddMvc(options =>
 6  
 7 {
 8  
 9 options.Filters.Add(typeof(AuthorizationFilters));// 自定義一個類AuthorizationFilters,添加身份驗證過濾器
10  
11 });
12  
13 }
14  
15  
16  
17 /// <summary>
18  
19 /// 身份認證類繼承IAuthorizationFilter接口
20  
21 /// </summary>
22  
23 public class AuthorizationFilters :IAuthorizationFilter
24  
25 {
26  
27 /// <summary>
28  
29 /// 請求驗證,當前驗證部分不要拋出異常,ExceptionFilter不會處理
30  
31 /// </summary>
32  
33 /// <param name="context">請求內容信息</param>
34  
35 public void OnAuthorization(AuthorizationFilterContext context)
36  
37 {
38  
39 //寫本身的邏輯
40  
41 }
42  
43 }

 

13.使用session和解決sessionID一直變化的問題

NET Core版本:

在Startup類裏添加session配置

 
 1 public void ConfigureServices(IServiceCollection services)
 2  
 3 {
 4  
 5 services.AddDistributedMemoryCache();
 6  
 7 services.AddSession(option =>
 8  
 9 { //設置session過時時間
10  
11 option.IOTimeout = TimeSpan.FromHours(1);
12  
13 option.IdleTimeout = TimeSpan.FromHours(1);
14  
15 });
16  
17 services.AddMvc();
18  
19 }
20  
21  
22  
23 public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider svp)
24  
25 {
26  
27 app.UseSession();//必須在app.UseMvc以前,不然報錯
28  
29 app.UseMvc(routes =>
30  
31 {
32  
33 routes.MapRoute(
34  
35 name: "default",
36  
37 template: "{controller=Home}/{action=Index}/{id?}");
38  
39 });
40  
41 }

 

配置完成後session就可使用了,不過當Session保存有值,id纔不會改變,沒有值每次刷新都會變,能夠給在使用session時能夠給session隨便賦個值以保證sessionid不會一直變化。

 
1 HttpContext.Session.Set("login", Encoding.UTF8.GetBytes("login"));
2  
3 string sessionid = HttpContext.Session.Id;

14.MD5加密

NET Framework版本:

1  
2 //參數str類型是string
3  
4 System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");

 

NET Core版本:用如下這個方法替換了

 
 1 /// <summary>
 2  
 3 /// 32位MD5加密
 4  
 5 /// </summary>
 6  
 7 /// <param name="input"></param>
 8  
 9 /// <returns></returns>
10  
11 private static string Md5Hash(string input)
12  
13 {
14  
15 MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
16  
17 byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
18  
19 StringBuilder sBuilder = new StringBuilder();
20  
21 for (int i = 0; i < data.Length; i++)
22  
23 {
24  
25 sBuilder.Append(data[i].ToString("x2"));
26  
27 }
28  
29 return sBuilder.ToString();
30  
31 }

 

15.Path.Combine()

該方法是路徑拼接,在NET Framework版本和NET Core版本一樣支持,不過用Path.Combine拼接出來的路徑是這樣的:xxxx\\xxxx,用的是「\\」,這種路徑在Window系統上能夠正常運行,可是在Linux上是沒法定位到準確的路徑的。Linux上的路徑是這樣的:xxxx/xxxx。因此當咱們用Path.Combine這個方法時最好再配合一個替換方法:

Path.Combine(path1,path2).Replace("\\","/");

 

16.DateTime

1  // 方法在不一樣平臺返回的時間格式不同,即便使用ToString("yyyy/MM/dd")但願轉成'2019/04/18'這種格式,但在Centos7平臺下它仍是變成了‘2019-04-18’這樣,能夠考慮用Replace方法去替換。
2   core 2.1 DateTime.Now.ToString() 

 原文地址:https://www.cnblogs.com/lonelyxmas/p/12001657.html
相關文章
相關標籤/搜索