1 namespace System.Web.Mvc.Html {
2 using System.Collections.Generic;
3 using System.Globalization;
6 using System.Web.Mvc.Resources;
7 using System.Web.Routing;
9 public static class ChildActionExtensions {
13 public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName) {
14 return Action(htmlHelper, actionName, null /* controllerName */, null /* routeValues */);
17 public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, object routeValues) {
18 return Action(htmlHelper, actionName, null /* controllerName */, new RouteValueDictionary(routeValues));
21 public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues) {
22 return Action(htmlHelper, actionName, null /* controllerName */, routeValues);
25 public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName) {
26 return Action(htmlHelper, actionName, controllerName, null /* routeValues */);
29 public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) {
30 return Action(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues));
33 public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) {
34 using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture)) {
35 ActionHelper(htmlHelper, actionName, controllerName, routeValues, writer);
36 return MvcHtmlString.Create(writer.ToString());
42 public static void RenderAction(this HtmlHelper htmlHelper, string actionName) {
43 RenderAction(htmlHelper, actionName, null /* controllerName */, null /* routeValues */);
46 public static void RenderAction(this HtmlHelper htmlHelper, string actionName, object routeValues) {
47 RenderAction(htmlHelper, actionName, null /* controllerName */, new RouteValueDictionary(routeValues));
50 public static void RenderAction(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues) {
51 RenderAction(htmlHelper, actionName, null /* controllerName */, routeValues);
54 public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName) {
55 RenderAction(htmlHelper, actionName, controllerName, null /* routeValues */);
58 public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) {
59 RenderAction(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues));
62 public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) {
63 ActionHelper(htmlHelper, actionName, controllerName, routeValues, htmlHelper.ViewContext.Writer);
68 internal static void ActionHelper(HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, TextWriter textWriter) {
69 if (htmlHelper == null) {
70 throw new ArgumentNullException("htmlHelper");
72 if (String.IsNullOrEmpty(actionName)) {
73 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
76 RouteValueDictionary additionalRouteValues = routeValues;
77 routeValues = MergeDictionaries(routeValues, htmlHelper.ViewContext.RouteData.Values);
79 routeValues["action"] = actionName;
80 if (!String.IsNullOrEmpty(controllerName)) {
81 routeValues["controller"] = controllerName;
85 VirtualPathData vpd = htmlHelper.RouteCollection.GetVirtualPathForArea(htmlHelper.ViewContext.RequestContext, null /* name */, routeValues, out usingAreas);
87 throw new InvalidOperationException(MvcResources.Common_NoRouteMatched);
91 routeValues.Remove("area");
92 if (additionalRouteValues != null) {
93 additionalRouteValues.Remove("area");
97 if (additionalRouteValues != null) {
98 routeValues[ChildActionValueProvider.ChildActionValuesKey] = new DictionaryValueProvider<object>(additionalRouteValues, CultureInfo.InvariantCulture);
101 RouteData routeData = CreateRouteData(vpd.Route, routeValues, vpd.DataTokens, htmlHelper.ViewContext);
102 HttpContextBase httpContext = htmlHelper.ViewContext.HttpContext;
103 RequestContext requestContext = new RequestContext(httpContext, routeData);
104 ChildActionMvcHandler handler = new ChildActionMvcHandler(requestContext);
105 httpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(handler), textWriter, true /* preserveForm */);
108 private static RouteData CreateRouteData(RouteBase route, RouteValueDictionary routeValues, RouteValueDictionary dataTokens, ViewContext parentViewContext) {
109 RouteData routeData = new RouteData();
111 foreach (KeyValuePair<string, object> kvp in routeValues) {
112 routeData.Values.Add(kvp.Key, kvp.Value);
115 foreach (KeyValuePair<string, object> kvp in dataTokens) {
116 routeData.DataTokens.Add(kvp.Key, kvp.Value);
119 routeData.Route = route;
120 routeData.DataTokens[ControllerContext.PARENT_ACTION_VIEWCONTEXT] = parentViewContext;
124 private static RouteValueDictionary MergeDictionaries(params RouteValueDictionary[] dictionaries) {
125 // Merge existing route values with the user provided values
126 var result = new RouteValueDictionary();
128 foreach (RouteValueDictionary dictionary in dictionaries.Where(d => d != null)) {
129 foreach (KeyValuePair<string, object> kvp in dictionary) {
130 if (!result.ContainsKey(kvp.Key)) {
131 result.Add(kvp.Key, kvp.Value);
139 internal class ChildActionMvcHandler : MvcHandler {
140 public ChildActionMvcHandler(RequestContext context)
144 protected internal override void AddVersionHeader(HttpContextBase httpContext) {
145 // No version header for child actions