Asp.Net Core 2.0實現HttpResponse中繁切換
阿新 • • 發佈:2018-07-27
== sed 存儲 中文簡體 選擇 .net tin contains nts
隨筆背景:因為項目中有個簡單的功能是需要實現中文簡體到繁體的切換,數據庫中存儲的源數據都是中文簡體的,為了省事就想著通過HttpHeader的方式來控制Api返回對應的繁體數據。
實現方式:通過Asp.Net Core 中的中間件來攔截HttpResponse,然後通過轉換字符編碼來實現中文繁體切換。
實現代碼如下:
HttpContextMiddleware 中間件
public class HttpContextMiddleware { private readonly RequestDelegate _next; public HttpContextMiddleware(RequestDelegate next) { _next= next; } public async Task Invoke(HttpContext context) { var originalBodyStream = context.Response.Body; using (var responseBody = new MemoryStream()) { context.Response.Body = responseBody; await_next(context); var result = await FormatResponse(context.Response); if (context.Request.Headers.Keys.Contains(Constants.HttpHeaderLanguage)) { var lang = context.Request.Headers.GetCommaSeparatedValues(Constants.HttpHeaderLanguage).GetValue(0).ToString(); if (lang == "zh-tw") { var traditionresult = ConvertHelper.ToTraditional(result); byte[] array = Encoding.UTF8.GetBytes(traditionresult); MemoryStream stream = new MemoryStream(array); try { await stream.CopyToAsync(originalBodyStream); } catch (Exception ex) { throw ex; } } else { try { await responseBody.CopyToAsync(originalBodyStream); } catch (Exception ex) { throw ex; } } } else { await responseBody.CopyToAsync(originalBodyStream); } } } private async Task<string> FormatResponse(HttpResponse response) { response.Body.Seek(0, SeekOrigin.Begin); var text = await new StreamReader(response.Body).ReadToEndAsync(); response.Body.Seek(0, SeekOrigin.Begin); return $"{text}"; } }
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseDefaultFiles(); app.UseAuthentication(); app.UseStaticFiles(); //在Mvc之前註入到管道中 app.UseMiddleware<HttpContextMiddleware>(); app.UseMvc(); }
ConvertHelper 中文簡體繁體轉換工具類
public static class ConvertHelper { private const int LOCALE_SYSTEM_DEFAULT = 0x0800; private const int LCMAP_SIMPLIFIED_CHINESE = 0x02000000; private const int LCMAP_TRADITIONAL_CHINESE = 0x04000000; [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] private static extern int LCMapString(int Locale, int dwMapFlags, string lpSrcStr, int cchSrc, [Out] string lpDestStr, int cchDest); /// <summary> /// 將字符轉換成簡體中文 /// </summary> /// <param name="source">輸入要轉換的字符串</param> /// <returns>轉換完成後的字符串</returns> public static string ToSimplified(string source) { String target = new String(‘ ‘, source.Length); int ret = LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_SIMPLIFIED_CHINESE, source, source.Length, target, source.Length); return target; } /// <summary> /// 將字符轉換為繁體中文 /// </summary> /// <param name="source">輸入要轉換的字符串</param> /// <returns>轉換完成後的字符串</returns> public static string ToTraditional(string source) { String target = new String(‘ ‘, source.Length); int ret = LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_TRADITIONAL_CHINESE, source, source.Length, target, source.Length); return target; } }
以上源代碼就是所有關鍵代碼了,中間件註入以後,不用再在action裏或controller裏單獨攔截,經測試,會攔截所有api的響應結果。這裏有個插曲是我之前嘗試過使用ResultFilter來攔截,但沒法做到在響應後攔截響應結果。不知出於什麽原因,最後我放棄了Filter的方式,選擇了這種中間件的攔截方式。
本文參考如下:
https://elanderson.net/2017/02/log-requests-and-responses-in-asp-net-core/
本文如有不對的地方,歡迎指正!願與君共勉。
最後,感謝您的閱讀!
Asp.Net Core 2.0實現HttpResponse中繁切換