常見.NET功能代碼彙總 (2)

常見.NET功能代碼彙總html

23,獲取和設置分級緩存

獲取緩存:首先從本地緩存獲取,若是沒有,再去讀取分佈式緩存
寫緩存:同時寫本地緩存和分佈式緩存node

  private static T GetGradeCache<T>(string key) where T:struct 
        {
            MemoryCacheManager localCache = MemoryCacheManager.Instance;
            if (!localCache.IsSet(key))
            {
                //本地不存在此緩存
               T  remoteValue = MemCacheManager.Instance.Get<T>(key);
               if (!ValueType.Equals(remoteValue, default(T)))
               { 
                    //若是遠程有
                   localCache.Set(key, remoteValue, 1); 
               }
               else
               {
                   localCache.SetFromSeconds(key, default(T), 10); 
               }
               return remoteValue;
            }
            T value = localCache.Get<T>(key);
            return value;
        }

        private static void SetGradeCache<T>(string key,T Value,int time) where T : struct 
        {
            MemoryCacheManager localCache = MemoryCacheManager.Instance;
            localCache.Remove(key);
            localCache.Set(key, Value, time);
            MemCacheManager.Instance.Remove(key);
            MemCacheManager.Instance.Set(key, Value, time); 
        }

24,求相對目錄的絕對路徑

有時候,咱們須要求相對於當前根目錄的相對目錄,好比將日誌文件存儲在站點目錄以外,咱們可使用 ../logs/ 的方式:web

 string vfileName = string.Format("../logs/{0}_{1}_{2}.log", logFileName, System.Environment.MachineName, DateTime.Now.ToString("yyyyMMdd"));
            string rootPath = HttpContext.Current.Server.MapPath("/");
            string targetPath = System.IO.Path.Combine(rootPath, vfileName);
            string fileName = System.IO.Path.GetFullPath(targetPath);
            string fileDir = System.IO.Path.GetDirectoryName(fileName);
            if (!System.IO.Directory.Exists(fileDir))
                System.IO.Directory.CreateDirectory(fileDir);

這個代碼會在站點目錄以外的日誌目錄,創建一個 代機器名稱的按照日期區分的日誌文件。後端

25,屢次嘗試寫日誌文件方法

日誌文件可能會併發的寫入,此時可能會提示「文件被另一個進程佔用」,所以能夠屢次嘗試寫入。下面的方法會遞歸的進行文件寫入嘗試,若是嘗試次數用完纔會最終報錯。數組

  /// <summary>
        /// 保存日誌文件
        /// </summary>
        /// <param name="logFileName">不帶擴展名文件名</param>
        /// <param name="logText">日誌內容</param>
        /// <param name="tryCount">若是出錯的嘗試次數,建議不大於100,若是是0則不嘗試</param>
        public static void SaveLog(string logFileName, string logText, int tryCount)
        {
            string vfileName = string.Format("..\\logs\\{0}_{1}_{2}.log", logFileName, System.Environment.MachineName, DateTime.Now.ToString("yyyyMMdd"));
            string rootPath = System.AppDomain.CurrentDomain.BaseDirectory;
            string targetPath = System.IO.Path.Combine(rootPath, vfileName);
            string fileName = System.IO.Path.GetFullPath(targetPath);
            string fileDir = System.IO.Path.GetDirectoryName(fileName);
            if (!System.IO.Directory.Exists(fileDir))
                System.IO.Directory.CreateDirectory(fileDir);
            
            try
            {
                System.IO.File.AppendAllText(fileName, logText);
                tryCount = 0;
            }
            catch (Exception ex)
            {
                if (tryCount > 0)
                {
                    System.Threading.Thread.Sleep(1000);
                    logText = logText + "\r\nSaveLog,try again times =" + tryCount + " ,Error:" + ex.Message;
                    tryCount--;
                    SaveLog(logFileName, logText, tryCount);
                }
                else
                {
                    throw new Exception("Save log file Error,try count more times!");
                }
            }
        }

 26,ASP.NET獲取客戶端的IP地址

      string GetRemoteIP()
        {
            string result = HttpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (null == result || result == String.Empty)
            {
                result = HttpContext.Request.ServerVariables["REMOTE_ADDR"];
            }


            if (null == result || result == String.Empty)
            {
                result = HttpContext.Request.UserHostAddress;
            }
            return result;

27,ASP.NET MVC 在Action裏面獲取請求的URL

能夠分爲3種方式,
1)ASP.NET MVC 在控制器的默認Action裏面獲取請求其它Action的路徑
好比在默認的 Index Action裏面獲取路徑,以下:瀏覽器

string sso_url= "http://" + Request.Url.Authority + Request.Url.AbsolutePath + "/SSO?id=" + userid;

 2)在其它Action裏面獲取當前控制器的路徑 緩存

string ctrName = RouteData.Values["controller"].ToString();
 string redirectUrl = "http://" + Request.Url.Authority + "/" + ctrName + "/SSO?id=" + userid;

 3)直接獲取當前Action請求的路徑安全

string url=Request.Url.ToString();

 

28,ASP.NET MVC Action返回能夠在瀏覽器直接查看的純文本信息

須要指定Context的contentType 爲「text/plain」,代碼以下:多線程

 public ActionResult SendMessage()
 {
   string txt="你好!";
   return Content(text, "text/plain", System.Text.Encoding.UTF8);
  }

 29,使用Linq2XML讀寫XML

這裏主要使用XDocument,XElement對象來操做XML內容,以下代碼:併發

    public static class XDocumentExtentsion
    {
        //生成XML的申明部分
        public static string ToStringWithDeclaration(this XDocument doc, SaveOptions options = SaveOptions.DisableFormatting)
        {
            return doc.Declaration.ToString() + doc.ToString(options);
        }
    }

        public string CreateMsgResult(string loginUserId,string corpid, string msg,string ts)
        {
            var xDoc = new XDocument(
                new XDeclaration("1.0", "UTF-8", null),  
                new XElement("result",
                    new XElement("corpid", corpid),
                    new XElement("userid", loginUserId),
                    new XElement("ts", ts),
                    new XElement("sendmsg", msg)
                ));
            return xDoc.ToStringWithDeclaration();
        }

        public ResponseMessage ParseXMLString(string xml)
        {
            var xDoc = XDocument.Parse(xml);
            if (xDoc == null) return null;
            var root = xDoc.Element("result");
            if(root==null)
                throw new Exception ("not found the 'result' root node,input XML\r\n"+xml);
            ResponseMessage result =
             new ResponseMessage()
             {
                 ErrorCode  = root.Element("rescode").Value,
                 ErrorMessage  = root.Element("resmsg").Value,
                 RedirectUrl  = root.Element("redirect_url") == null ? "" : root.Element("redirect_url").Value
             };
          
            return result;
        }

 30,訪問Web內容的自定義代碼

使用 HttpWebRequest和HttpWebResponse 對象完成Web訪問,若是是.NET 4.5,建議直接使用 HttpClient對象:

        /// <summary>
        /// 獲取請求結果
        /// </summary>
        /// <param name="requestUrl">請求地址</param>
        /// <param name="timeout">超時時間(秒)</param>
        /// <param name="requestXML">請求xml內容</param>
        /// <param name="isPost">是否post提交</param>
        /// <param name="encoding">編碼格式 例如:utf-8</param>
        /// <param name="errorMsg">拋出的錯誤信息</param>
        /// <returns>返回請求結果</returns>
        public static string HttpWebRequest(string requestUrl, int timeout, string requestXML, bool isPost, string encoding, out string errorMsg, string contentType = "application/x-www-form-urlencoded")
        {
            errorMsg = string.Empty;
            string result = string.Empty;
            try
            {
                byte[] bytes = System.Text.Encoding.GetEncoding(encoding).GetBytes(requestXML);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
                request.Referer = requestUrl;
                request.Method = isPost ? "POST" : "GET";
                request.Timeout = timeout * 1000;
                if (isPost)
                {
                    request.ContentType = contentType;// "application/x-www-form-urlencoded";
                    request.ContentLength = bytes.Length;
                    using (Stream requestStream = request.GetRequestStream())
                    {
                        requestStream.Write(bytes, 0, bytes.Length);
                        requestStream.Close();
                    }
                }
                
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                if (responseStream != null)
                {
                    StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.GetEncoding(encoding));
                    result = reader.ReadToEnd();
                    reader.Close();
                    responseStream.Close();
                    request.Abort();
                    response.Close();
                    return result.Trim();
                }
            }
            catch (Exception ex)
            {
                errorMsg =string.Format("Error Message:{0},Request Url:{1},StackTrace:{2}", ex.Message ,requestUrl , ex.StackTrace);
            }

            return result;
        }

 31,自定義瀏覽器協議(僞協議),實現web程序調用本地程序

(轉自 http://blog.sina.com.cn/s/blog_4a77f0630100hav3.html
最近項目遇到這麼個問題。客戶要求用web頁面,點擊一個連接,調用本地的一個程序。

參考了一下qq的方式。
tencent://Message/?Uin=000000&websiteName=qzone.qq.com&Menu=yes

在註冊表裏面添加下面,就能實現,詳細內容見原文

 

32,線程安全的向集合添加元素

有時候,向一個List對象調用Add 方法,會出現「索引超出了數組界限」這樣的問題,此時能夠考慮使用線程安全的集合,但對於業務上設定了集合的最大值的狀況下,用線程安全集合就有點重了,效率不高,此時能夠經過 Interlocked.CompareExchange 來實現,具體代碼以下:

private int length=0;
private int maxLength=50;
private int[] Arr=new int[maxLength];

//使用循環數組,安全的添加元素
void Add(int value){
  int p= Interlocked.CompareExchange(ref length,0,maxLength);
  if(p==length) 
  {
      //說明length變量而且沒有達到最大值,並安全的返回length當時的值
      Arr[p]=value;
  }
  else
  {
      //數組元素已經達到上限,須要觸發另外的操做,好比將數組所有輸出
      // To Do
      //以後,再將當前位置的元素寫入
      //此時,length多是0,也多是其它值
      Arr[length]=value;
  }
  Interlocked.Increment(ref length);
}

 

 33,WPF綁定異步更新的數據集合

最近作一個WPF項目,後端API推送過來的數據要更新WPF界面的數據,發現有些數據沒有跟後端數據狀態一致。一般狀況下,WPF綁定的Model數據集合都是繼承於ObservableCollection 的,可是在當前狀況下會有問題,這是能夠封裝一個異步的數據集合:

public class AsyncObservableCollection<T> : ObservableCollection<T>
{
    //獲取當前線程的SynchronizationContext對象
    private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;
    public AsyncObservableCollection() { }
    public AsyncObservableCollection(IEnumerable<T> list) : base(list) { }
    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
          
        if (SynchronizationContext.Current == _synchronizationContext)
        {
            //若是操做發生在同一個線程中,不須要進行跨線程執行         
            RaiseCollectionChanged(e);
        }
        else
        {
            //若是不是發生在同一個線程中
            //準確說來,這裏是在一個非UI線程中,須要進行UI的更新所進行的操做         
            _synchronizationContext.Post(RaiseCollectionChanged, e);
        }
    }
    private void RaiseCollectionChanged(object param)
    {
        // 執行         
        base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
    }
    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (SynchronizationContext.Current == _synchronizationContext)
        {
            // Execute the PropertyChanged event on the current thread             
            RaisePropertyChanged(e);
        }
        else
        {
            // Post the PropertyChanged event on the creator thread             
            _synchronizationContext.Post(RaisePropertyChanged, e);
        }
    }
    private void RaisePropertyChanged(object param)
    {
        // We are in the creator thread, call the base implementation directly         
        base.OnPropertyChanged((PropertyChangedEventArgs)param);
    }
}

更多信息,請參考:

WPF多線程UI更新——兩種方法

綁定到異步的ObservableCollection

相關文章
相關標籤/搜索