1. 程式人生 > >Asp.Net Core 2.0實現HttpResponse中繁切換

Asp.Net Core 2.0實現HttpResponse中繁切換

== 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中繁切換