| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540 |
- using System;
- using System.Collections.Generic;
- using System.Configuration;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Web;
- using System.Web.Hosting;
- namespace GreenTree.Nachtragsmanagement.Core
- {
- public class WebHelper
- {
- #region Fields
- private readonly HttpContextBase _httpContext;
- #endregion
- #region Utilities
- protected virtual Boolean IsRequestAvailable(HttpContextBase httpContext)
- {
- if (httpContext == null)
- return false;
- try
- {
- if (httpContext.Request == null)
- return false;
- }
- catch (HttpException)
- {
- return false;
- }
- return true;
- }
- protected virtual bool TryWriteWebConfig()
- {
- try
- {
- // In medium trust, "UnloadAppDomain" is not supported. Touch web.config
- // to force an AppDomain restart.
- File.SetLastWriteTimeUtc(MapPath("~/web.config"), DateTime.UtcNow);
- return true;
- }
- catch
- {
- return false;
- }
- }
- protected virtual bool TryWriteGlobalAsax()
- {
- try
- {
- //When a new plugin is dropped in the Plugins folder and is installed into nopCommerce,
- //even if the plugin has registered routes for its controllers,
- //these routes will not be working as the MVC framework couldn't
- //find the new controller types and couldn't instantiate the requested controller.
- //That's why you get these nasty errors
- //i.e "Controller does not implement IController".
- //The issue is described here: http://www.nopcommerce.com/boards/t/10969/nop-20-plugin.aspx?p=4#51318
- //The solution is to touch global.asax file
- File.SetLastWriteTimeUtc(MapPath("~/global.asax"), DateTime.UtcNow);
- return true;
- }
- catch
- {
- return false;
- }
- }
- #endregion
- #region Methods
- /// <summary>
- /// Ctor
- /// </summary>
- /// <param name="httpContext">HTTP context</param>
- public WebHelper(HttpContextBase httpContext)
- {
- _httpContext = httpContext;
- }
- /// <summary>
- /// Get URL referrer
- /// </summary>
- /// <returns>URL referrer</returns>
- public virtual string GetUrlReferrer()
- {
- string referrerUrl = string.Empty;
- //URL referrer is null in some case (for example, in IE 8)
- if (IsRequestAvailable(_httpContext) && _httpContext.Request.UrlReferrer != null)
- referrerUrl = _httpContext.Request.UrlReferrer.PathAndQuery;
- return referrerUrl;
- }
- /// <summary>
- /// Get context IP address
- /// </summary>
- /// <returns>URL referrer</returns>
- public virtual string GetCurrentIpAddress()
- {
- if (!IsRequestAvailable(_httpContext))
- return string.Empty;
- var result = "";
- if (_httpContext.Request.Headers != null)
- {
- //The X-Forwarded-For (XFF) HTTP header field is a de facto standard
- //for identifying the originating IP address of a client
- //connecting to a web server through an HTTP proxy or load balancer.
- var forwardedHttpHeader = "X-FORWARDED-FOR";
- if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["ForwardedHTTPheader"]))
- {
- //but in some cases server use other HTTP header
- //in these cases an administrator can specify a custom Forwarded HTTP header
- forwardedHttpHeader = ConfigurationManager.AppSettings["ForwardedHTTPheader"];
- }
- //it's used for identifying the originating IP address of a client connecting to a web server
- //through an HTTP proxy or load balancer.
- string xff = _httpContext.Request.Headers.AllKeys
- .Where(x => forwardedHttpHeader.Equals(x, StringComparison.InvariantCultureIgnoreCase))
- .Select(k => _httpContext.Request.Headers[k])
- .FirstOrDefault();
- //if you want to exclude private IP addresses, then see http://stackoverflow.com/questions/2577496/how-can-i-get-the-clients-ip-address-in-asp-net-mvc
- if (!String.IsNullOrEmpty(xff))
- {
- string lastIp = xff.Split(new[] { ',' }).FirstOrDefault();
- result = lastIp;
- }
- }
- if (String.IsNullOrEmpty(result) && _httpContext.Request.UserHostAddress != null)
- {
- result = _httpContext.Request.UserHostAddress;
- }
- //some validation
- if (result == "::1")
- result = "127.0.0.1";
- //remove port
- if (!String.IsNullOrEmpty(result))
- {
- int index = result.IndexOf(":", StringComparison.InvariantCultureIgnoreCase);
- if (index > 0)
- result = result.Substring(0, index);
- }
- return result;
- }
- /// <summary>
- /// Gets a value indicating whether current connection is secured
- /// </summary>
- /// <returns>true - secured, false - not secured</returns>
- public virtual bool IsCurrentConnectionSecured()
- {
- bool useSsl = false;
- if (IsRequestAvailable(_httpContext))
- {
- useSsl = _httpContext.Request.IsSecureConnection;
- //when your hosting uses a load balancer on their server then the Request.IsSecureConnection is never got set to true, use the statement below
- //just uncomment it
- //useSSL = _httpContext.Request.ServerVariables["HTTP_CLUSTER_HTTPS"] == "on" ? true : false;
- }
- return useSsl;
- }
- /// <summary>
- /// Gets server variable by name
- /// </summary>
- /// <param name="name">Name</param>
- /// <returns>Server variable</returns>
- public virtual string ServerVariables(string name)
- {
- string result = string.Empty;
- try
- {
- if (!IsRequestAvailable(_httpContext))
- return result;
- //put this method is try-catch
- //as described here http://www.nopcommerce.com/boards/t/21356/multi-store-roadmap-lets-discuss-update-done.aspx?p=6#90196
- if (_httpContext.Request.ServerVariables[name] != null)
- {
- result = _httpContext.Request.ServerVariables[name];
- }
- }
- catch
- {
- result = string.Empty;
- }
- return result;
- }
- /// <summary>
- /// Returns true if the requested resource is one of the typical resources that needn't be processed by the cms engine.
- /// </summary>
- /// <param name="request">HTTP Request</param>
- /// <returns>True if the request targets a static resource file.</returns>
- /// <remarks>
- /// These are the file extensions considered to be static resources:
- /// .css
- /// .gif
- /// .png
- /// .jpg
- /// .jpeg
- /// .js
- /// .axd
- /// .ashx
- /// </remarks>
- public virtual bool IsStaticResource(HttpRequest request)
- {
- if (request == null)
- throw new ArgumentNullException("request");
- string path = request.Path;
- string extension = VirtualPathUtility.GetExtension(path);
- if (extension == null) return false;
- switch (extension.ToLower())
- {
- case ".axd":
- case ".ashx":
- case ".bmp":
- case ".css":
- case ".gif":
- case ".htm":
- case ".html":
- case ".ico":
- case ".jpeg":
- case ".jpg":
- case ".js":
- case ".png":
- case ".rar":
- case ".zip":
- return true;
- }
- return false;
- }
- /// <summary>
- /// Maps a virtual path to a physical disk path.
- /// </summary>
- /// <param name="path">The path to map. E.g. "~/bin"</param>
- /// <returns>The physical path. E.g. "c:\inetpub\wwwroot\bin"</returns>
- public virtual string MapPath(string path)
- {
- if (HostingEnvironment.IsHosted)
- {
- //hosted
- return HostingEnvironment.MapPath(path);
- }
- //not hosted. For example, run in unit tests
- string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
- path = path.Replace("~/", "").TrimStart('/').Replace('/', '\\');
- return Path.Combine(baseDirectory, path);
- }
- /// <summary>
- /// Modifies query string
- /// </summary>
- /// <param name="url">Url to modify</param>
- /// <param name="queryStringModification">Query string modification</param>
- /// <param name="anchor">Anchor</param>
- /// <returns>New url</returns>
- public virtual string ModifyQueryString(string url, string queryStringModification, string anchor)
- {
- if (url == null)
- url = string.Empty;
- url = url.ToLowerInvariant();
- if (queryStringModification == null)
- queryStringModification = string.Empty;
- queryStringModification = queryStringModification.ToLowerInvariant();
- if (anchor == null)
- anchor = string.Empty;
- anchor = anchor.ToLowerInvariant();
- string str = string.Empty;
- string str2 = string.Empty;
- if (url.Contains("#"))
- {
- str2 = url.Substring(url.IndexOf("#") + 1);
- url = url.Substring(0, url.IndexOf("#"));
- }
- if (url.Contains("?"))
- {
- str = url.Substring(url.IndexOf("?") + 1);
- url = url.Substring(0, url.IndexOf("?"));
- }
- if (!string.IsNullOrEmpty(queryStringModification))
- {
- if (!string.IsNullOrEmpty(str))
- {
- var dictionary = new Dictionary<string, string>();
- foreach (string str3 in str.Split(new[] { '&' }))
- {
- if (!string.IsNullOrEmpty(str3))
- {
- string[] strArray = str3.Split(new[] { '=' });
- if (strArray.Length == 2)
- {
- if (!dictionary.ContainsKey(strArray[0]))
- {
- //do not add value if it already exists
- //two the same query parameters? theoretically it's not possible.
- //but MVC has some ugly implementation for checkboxes and we can have two values
- //find more info here: http://www.mindstorminteractive.com/topics/jquery-fix-asp-net-mvc-checkbox-truefalse-value/
- //we do this validation just to ensure that the first one is not overridden
- dictionary[strArray[0]] = strArray[1];
- }
- }
- else
- {
- dictionary[str3] = null;
- }
- }
- }
- foreach (string str4 in queryStringModification.Split(new[] { '&' }))
- {
- if (!string.IsNullOrEmpty(str4))
- {
- string[] strArray2 = str4.Split(new[] { '=' });
- if (strArray2.Length == 2)
- {
- dictionary[strArray2[0]] = strArray2[1];
- }
- else
- {
- dictionary[str4] = null;
- }
- }
- }
- var builder = new StringBuilder();
- foreach (string str5 in dictionary.Keys)
- {
- if (builder.Length > 0)
- {
- builder.Append("&");
- }
- builder.Append(str5);
- if (dictionary[str5] != null)
- {
- builder.Append("=");
- builder.Append(dictionary[str5]);
- }
- }
- str = builder.ToString();
- }
- else
- {
- str = queryStringModification;
- }
- }
- if (!string.IsNullOrEmpty(anchor))
- {
- str2 = anchor;
- }
- return (url + (string.IsNullOrEmpty(str) ? "" : ("?" + str)) + (string.IsNullOrEmpty(str2) ? "" : ("#" + str2))).ToLowerInvariant();
- }
- /// <summary>
- /// Remove query string from url
- /// </summary>
- /// <param name="url">Url to modify</param>
- /// <param name="queryString">Query string to remove</param>
- /// <returns>New url</returns>
- public virtual string RemoveQueryString(string url, string queryString)
- {
- if (url == null)
- url = string.Empty;
- url = url.ToLowerInvariant();
- if (queryString == null)
- queryString = string.Empty;
- queryString = queryString.ToLowerInvariant();
- string str = string.Empty;
- if (url.Contains("?"))
- {
- str = url.Substring(url.IndexOf("?") + 1);
- url = url.Substring(0, url.IndexOf("?"));
- }
- if (!string.IsNullOrEmpty(queryString))
- {
- if (!string.IsNullOrEmpty(str))
- {
- var dictionary = new Dictionary<string, string>();
- foreach (string str3 in str.Split(new[] { '&' }))
- {
- if (!string.IsNullOrEmpty(str3))
- {
- string[] strArray = str3.Split(new[] { '=' });
- if (strArray.Length == 2)
- {
- dictionary[strArray[0]] = strArray[1];
- }
- else
- {
- dictionary[str3] = null;
- }
- }
- }
- dictionary.Remove(queryString);
- var builder = new StringBuilder();
- foreach (string str5 in dictionary.Keys)
- {
- if (builder.Length > 0)
- {
- builder.Append("&");
- }
- builder.Append(str5);
- if (dictionary[str5] != null)
- {
- builder.Append("=");
- builder.Append(dictionary[str5]);
- }
- }
- str = builder.ToString();
- }
- }
- return (url + (string.IsNullOrEmpty(str) ? "" : ("?" + str)));
- }
- /// <summary>
- /// Gets query string value by name
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="name">Parameter name</param>
- /// <returns>Query string value</returns>
- public virtual T QueryString<T>(string name)
- {
- string queryParam = null;
- if (IsRequestAvailable(_httpContext) && _httpContext.Request.QueryString[name] != null)
- queryParam = _httpContext.Request.QueryString[name];
- if (!String.IsNullOrEmpty(queryParam))
- return CommonHelper.To<T>(queryParam);
- return default(T);
- }
- /// <summary>
- /// Restart application domain
- /// </summary>
- /// <param name="makeRedirect">A value indicating whether we should made redirection after restart</param>
- /// <param name="redirectUrl">Redirect URL; empty string if you want to redirect to the current page URL</param>
- public virtual void RestartAppDomain(bool makeRedirect = false, string redirectUrl = "")
- {
- if (CommonHelper.GetTrustLevel() > AspNetHostingPermissionLevel.Medium)
- {
- //full trust
- HttpRuntime.UnloadAppDomain();
- TryWriteGlobalAsax();
- }
- else
- {
- //medium trust
- bool success = TryWriteWebConfig();
- if (!success)
- {
- throw new Exception("The application needs to be restarted due to a configuration change, but was unable to do so." + Environment.NewLine +
- "To prevent this issue in the future, a change to the web server configuration is required:" + Environment.NewLine +
- "- run the application in a full trust environment, or" + Environment.NewLine +
- "- give the application write access to the 'web.config' file.");
- }
- success = TryWriteGlobalAsax();
- if (!success)
- {
- throw new Exception("The application needs to be restarted due to a configuration change, but was unable to do so." + Environment.NewLine +
- "To prevent this issue in the future, a change to the web server configuration is required:" + Environment.NewLine +
- "- run the application in a full trust environment, or" + Environment.NewLine +
- "- give the application write access to the 'Global.asax' file.");
- }
- }
- // If setting up extensions/modules requires an AppDomain restart, it's very unlikely the
- // current request can be processed correctly. So, we redirect to the same URL, so that the
- // new request will come to the newly started AppDomain.
- if (_httpContext != null && makeRedirect)
- {
- if (String.IsNullOrEmpty(redirectUrl))
- redirectUrl = "~/";
- _httpContext.Response.Redirect(redirectUrl, true /*endResponse*/);
- }
- }
- /// <summary>
- /// Gets a value that indicates whether the client is being redirected to a new location
- /// </summary>
- public virtual bool IsRequestBeingRedirected
- {
- get
- {
- var response = _httpContext.Response;
- return response.IsRequestBeingRedirected;
- }
- }
- /// <summary>
- /// Gets or sets a value that indicates whether the client is being redirected to a new location using POST
- /// </summary>
- public virtual bool IsPostBeingDone
- {
- get
- {
- if (_httpContext.Items["nop.IsPOSTBeingDone"] == null)
- return false;
- return Convert.ToBoolean(_httpContext.Items["nop.IsPOSTBeingDone"]);
- }
- set
- {
- _httpContext.Items["nop.IsPOSTBeingDone"] = value;
- }
- }
- #endregion
- }
- }
|