Wednesday, December 4, 2013

AbsoluteActionLink, an extended method for HtmlHelper to render an absolute URL in ASP.NET MVC 3

using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace me.ExtensionMethods
{
    public static class Html
    {
        public static MvcHtmlString AbsoluteActionLink(this HtmlHelper htmlHelper, string text, string actionName, string controllerName, object routeValues, object htmlAttributes)
        {
            var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
            string baseUrl = BaseUrl(htmlHelper.ViewContext.RequestContext.HttpContext.Request, urlHelper.Content("~/"));
            var rd = CastBackTo(routeValues);
            string routelist = GetRouteData(rd);

            var htmls = CastBackTo(htmlAttributes);
            string htmlattributeslist = GetHtmlAttributes(htmls);

            var htmlstring = string.Format("{4}", baseUrl, actionName, controllerName, routelist, text, htmlattributeslist);
            return new MvcHtmlString(htmlstring);
        }

        private static string GetHtmlAttributes(RouteValueDictionary htmls)
        {
            string htmlattributeslist = "";
            foreach (var one in htmls.Keys)
            {
                object value = "";
                htmls.TryGetValue(one, out value);
                htmlattributeslist = htmlattributeslist + string.Format("{0}='{1}'", one, value);
            }
            return htmlattributeslist;
        }

        private static string GetRouteData(RouteValueDictionary rd)
        {
            string routelist = "";
            foreach (var one in rd.Values)
            {
                routelist = routelist + (routelist == "" ? "" : "/") + one;
            }
            return routelist;
        }
        
        public static RouteValueDictionary CastBackTo(object ob)
        {
            RouteValueDictionary result = new RouteValueDictionary();
            foreach (PropertyInfo property in ob.GetType().GetProperties())
            {
                result.Add(property.Name,  property.GetValue(ob, null));
            }
            return result;
        }

        public static string BaseUrl(HttpRequestBase Request, string rootpath)
        {
            var baseUrl = string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, rootpath);
            if (!baseUrl.ToLower().Contains("localhost"))
            {
                string result = "";
                string[] baseUrlSections = baseUrl.ToLower().Split("/".ToCharArray());
                foreach (var one in baseUrlSections)
                {
                    if (one.Contains(":") && !one.Contains("http"))
                    {
                        result = result + "/" + one.Substring(0, one.IndexOf(":"));
                    }
                    else
                    {
                        result = result + (result == "" ? "" : "/") + one;
                    }
                }
                baseUrl = result;
            }
            return baseUrl;
        }
    }
}