Search code examples
asp.net-mvchtml-helper

How to render partial view using url


I'm using ASP.NET MVC 4 and have a prepared url in a view like this:

var sectoionUrl = Url.Action("DisplayArticleSection", new { id = sectionId });

Is there any helper to render a partial view using prepared sectionUrl instead of creating it again via helper:

@Html.Action("DisplayArticleSection", new { id = sectionId })

?

Something like this pseudocode:

@Html.RenderUrl(sectionUrl)

Solution

  • Custom HtmlHelper:

    public static class RenderUrlHelper
    {
        public static void RenderUrl(this HtmlHelper helper, string originUrl)
        {
            var originRequest = helper.ViewContext.RequestContext.HttpContext.Request;
    
            if (!Uri.IsWellFormedUriString(originUrl, UriKind.Absolute))
            {
                originUrl = new Uri(originRequest.Url, originUrl).AbsoluteUri;
            }
    
            int queryIdx = originUrl.IndexOf('?');
            string queryString = null;
            string url = originUrl;
    
            if (queryIdx != -1)
            {
                url = originUrl.Substring(0, queryIdx);
                queryString = originUrl.Substring(queryIdx + 1);
            }
    
            // Extract the data and render the action.    
            var request = new HttpRequest(null, url, queryString);
            var response = new HttpResponse(new StringWriter());
            var httpContext = new HttpContext(request, response);
            var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
            var values = routeData.Values;
            string controllerName = values["controller"] as string;
            string actionName = values["action"] as string;
            var valuesCollection = HttpUtility.ParseQueryString(queryString);
            RouteValueDictionary routeValues = new RouteValueDictionary(valuesCollection.AllKeys.ToDictionary(k => k, k => (object)valuesCollection[k]));
            helper.RenderAction(actionName, controllerName, routeValues);
        }
    }
    

    Some code to test custom HtmlHelper:

    TestController:

    public class TestController : Controller
    {
        public ActionResult Index(string title, int number)
        {
            TestModel model = new TestModel { Title = title, Number = number };
            return PartialView(model);
        }
    }
    

    TestController Index view:

    @model TestModel
    
    <h1>Title: @Model.Title</h1>
    <h2>Number: @Model.Number</h2>
    

    TestModel:

    public class TestModel
    {
        public string Title { get; set; }
        public int Number { get; set; }
    }
    

    Usage in any view:

    @{
        var actionUrl = Url.Action("Index", "Test", new { number = 123, title = "Hello Url Renderer" });
        Html.RenderUrl(actionUrl);
    }