Merge branch '6.2.0' of https://github.com/umbraco/Umbraco-CMS into 6.2.0

This commit is contained in:
Morten Christensen
2013-09-05 11:28:45 +02:00
2 changed files with 346 additions and 64 deletions

View File

@@ -188,23 +188,29 @@ namespace Umbraco.Web
/// </summary>
internal class UmbracoForm : MvcForm
{
/// <summary>
/// Creates an UmbracoForm
/// </summary>
/// <param name="viewContext"></param>
/// <param name="surfaceController"></param>
/// <param name="surfaceAction"></param>
/// <param name="area"></param>
/// <param name="additionalRouteVals"></param>
public UmbracoForm(
/// <summary>
/// Creates an UmbracoForm
/// </summary>
/// <param name="viewContext"></param>
/// <param name="surfaceController"></param>
/// <param name="surfaceAction"></param>
/// <param name="area"></param>
/// <param name="method"></param>
/// <param name="additionalRouteVals"></param>
public UmbracoForm(
ViewContext viewContext,
string surfaceController,
string surfaceAction,
string area,
FormMethod method,
object additionalRouteVals = null)
: base(viewContext)
{
//need to create a params string as Base64 to put into our hidden field to use during the routes
_viewContext = viewContext;
_method = method;
//need to create a params string as Base64 to put into our hidden field to use during the routes
var surfaceRouteParams = string.Format("c={0}&a={1}&ar={2}",
viewContext.HttpContext.Server.UrlEncode(surfaceController),
viewContext.HttpContext.Server.UrlEncode(surfaceAction),
@@ -212,21 +218,19 @@ namespace Umbraco.Web
var additionalRouteValsAsQuery = additionalRouteVals != null ? additionalRouteVals.ToDictionary<object>().ToQueryString() : null;
if (!additionalRouteValsAsQuery.IsNullOrWhiteSpace())
if (additionalRouteValsAsQuery.IsNullOrWhiteSpace() == false)
surfaceRouteParams += "&" + additionalRouteValsAsQuery;
if (!string.IsNullOrWhiteSpace(surfaceRouteParams))
if (string.IsNullOrWhiteSpace(surfaceRouteParams) == false)
{
_encryptedString = surfaceRouteParams.EncryptWithMachineKey();
}
_textWriter = viewContext.Writer;
}
private readonly ViewContext _viewContext;
private readonly FormMethod _method;
private bool _disposed;
private readonly string _encryptedString;
private readonly TextWriter _textWriter;
protected override void Dispose(bool disposing)
{
@@ -234,13 +238,46 @@ namespace Umbraco.Web
return;
this._disposed = true;
//write out the hidden surface form routes
_textWriter.Write("<input name='uformpostroutevals' type='hidden' value='" + _encryptedString + "' />");
//Need to ensure any stale GET cookies are cleared before continuing
foreach (var c in _viewContext.HttpContext.Request.Cookies.AllKeys.Where(x => x.StartsWith("ufprt_")))
{
_viewContext.HttpContext.Request.Cookies[c].Expires = DateTime.Now.AddDays(-1);
_viewContext.HttpContext.Response.SetCookie(_viewContext.HttpContext.Request.Cookies[c]);
}
if (_method == FormMethod.Post)
{
//write out the hidden surface form routes
_viewContext.Writer.Write("<input name='ufprt' type='hidden' value='" + _encryptedString + "' />");
}
else
{
//since we are getting and we don't want this ugly value in the query string, we'll chuck it into a cookie with an id so we can retreive
//it on the server side with the same id and then remove it.
var id = Guid.NewGuid().ToString("N");
var cookie = new HttpCookie("ufprt_" + id, _encryptedString);
_viewContext.HttpContext.Response.SetCookie(cookie);
_viewContext.Writer.Write("<input name='ufprt' type='hidden' value='" + id + "' />");
}
base.Dispose(disposing);
}
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="controllerName"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName, FormMethod method)
{
return html.BeginUmbracoForm(action, controllerName, null, new Dictionary<string, object>(), method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
@@ -254,6 +291,20 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, controllerName, null, new Dictionary<string, object>());
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="controllerName"></param>
/// <param name="additionalRouteVals"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName, object additionalRouteVals, FormMethod method)
{
return html.BeginUmbracoForm(action, controllerName, additionalRouteVals, new Dictionary<string, object>(), method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
/// </summary>
@@ -267,7 +318,25 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, controllerName, additionalRouteVals, new Dictionary<string, object>());
}
/// <summary>
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="controllerName"></param>
/// <param name="additionalRouteVals"></param>
/// <param name="htmlAttributes"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName,
object additionalRouteVals,
object htmlAttributes,
FormMethod method)
{
return html.BeginUmbracoForm(action, controllerName, additionalRouteVals, htmlAttributes.ToDictionary<object>(), method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
/// </summary>
/// <param name="html"></param>
@@ -283,7 +352,28 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, controllerName, additionalRouteVals, htmlAttributes.ToDictionary<object>());
}
/// <summary>
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="controllerName"></param>
/// <param name="additionalRouteVals"></param>
/// <param name="htmlAttributes"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName,
object additionalRouteVals,
IDictionary<string, object> htmlAttributes,
FormMethod method)
{
Mandate.ParameterNotNullOrEmpty(action, "action");
Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName");
return html.BeginUmbracoForm(action, controllerName, "", additionalRouteVals, htmlAttributes, method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
/// </summary>
/// <param name="html"></param>
@@ -302,6 +392,19 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, controllerName, "", additionalRouteVals, htmlAttributes);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="surfaceType">The surface controller to route to</param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType, FormMethod method)
{
return html.BeginUmbracoForm(action, surfaceType, null, new Dictionary<string, object>(), method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
@@ -314,6 +417,20 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, surfaceType, null, new Dictionary<string, object>());
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action, FormMethod method)
where T : SurfaceController
{
return html.BeginUmbracoForm(action, typeof(T), method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
@@ -327,6 +444,21 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, typeof(T));
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="surfaceType">The surface controller to route to</param>
/// <param name="additionalRouteVals"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType,
object additionalRouteVals, FormMethod method)
{
return html.BeginUmbracoForm(action, surfaceType, additionalRouteVals, new Dictionary<string, object>(), method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
@@ -341,6 +473,21 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, surfaceType, additionalRouteVals, new Dictionary<string, object>());
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="additionalRouteVals"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action, object additionalRouteVals, FormMethod method)
where T : SurfaceController
{
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals, method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
@@ -355,7 +502,25 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals);
}
/// <summary>
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="surfaceType">The surface controller to route to</param>
/// <param name="additionalRouteVals"></param>
/// <param name="htmlAttributes"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType,
object additionalRouteVals,
object htmlAttributes,
FormMethod method)
{
return html.BeginUmbracoForm(action, surfaceType, additionalRouteVals, htmlAttributes.ToDictionary<object>(), method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
@@ -371,7 +536,25 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, surfaceType, additionalRouteVals, htmlAttributes.ToDictionary<object>());
}
/// <summary>
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="additionalRouteVals"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action,
object additionalRouteVals,
object htmlAttributes,
FormMethod method)
where T : SurfaceController
{
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals, htmlAttributes, method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <typeparam name="T"></typeparam>
@@ -388,7 +571,40 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals, htmlAttributes);
}
/// <summary>
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="surfaceType">The surface controller to route to</param>
/// <param name="additionalRouteVals"></param>
/// <param name="htmlAttributes"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType,
object additionalRouteVals,
IDictionary<string, object> htmlAttributes,
FormMethod method)
{
Mandate.ParameterNotNullOrEmpty(action, "action");
Mandate.ParameterNotNull(surfaceType, "surfaceType");
var area = "";
var surfaceController = SurfaceControllerResolver.Current.RegisteredSurfaceControllers
.SingleOrDefault(x => x == surfaceType);
if (surfaceController == null)
throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName);
var metaData = PluginController.GetMetadata(surfaceController);
if (metaData.AreaName.IsNullOrWhiteSpace() == false)
{
//set the area to the plugin area
area = metaData.AreaName;
}
return html.BeginUmbracoForm(action, metaData.ControllerName, area, additionalRouteVals, htmlAttributes, method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
@@ -400,26 +616,30 @@ namespace Umbraco.Web
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType,
object additionalRouteVals,
IDictionary<string, object> htmlAttributes)
{
Mandate.ParameterNotNullOrEmpty(action, "action");
Mandate.ParameterNotNull(surfaceType, "surfaceType");
{
return html.BeginUmbracoForm(action, surfaceType, additionalRouteVals, htmlAttributes, FormMethod.Post);
}
var area = "";
var surfaceController = SurfaceControllerResolver.Current.RegisteredSurfaceControllers
.SingleOrDefault(x => x == surfaceType);
if (surfaceController == null)
throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName);
var metaData = PluginController.GetMetadata(surfaceController);
if (!metaData.AreaName.IsNullOrWhiteSpace())
{
//set the area to the plugin area
area = metaData.AreaName;
}
return html.BeginUmbracoForm(action, metaData.ControllerName, area, additionalRouteVals, htmlAttributes);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="additionalRouteVals"></param>
/// <param name="htmlAttributes"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm<T>(this HtmlHelper html, string action,
object additionalRouteVals,
IDictionary<string, object> htmlAttributes,
FormMethod method)
where T : SurfaceController
{
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals, htmlAttributes, method);
}
/// <summary>
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <typeparam name="T"></typeparam>
@@ -436,6 +656,20 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, typeof(T), additionalRouteVals, htmlAttributes);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="controllerName"></param>
/// <param name="area"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName, string area, FormMethod method)
{
return html.BeginUmbracoForm(action, controllerName, area, null, new Dictionary<string, object>(), method);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
@@ -449,7 +683,30 @@ namespace Umbraco.Web
return html.BeginUmbracoForm(action, controllerName, area, null, new Dictionary<string, object>());
}
/// <summary>
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
/// <param name="action"></param>
/// <param name="controllerName"></param>
/// <param name="area"></param>
/// <param name="additionalRouteVals"></param>
/// <param name="htmlAttributes"></param>
/// <param name="method"></param>
/// <returns></returns>
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName, string area,
object additionalRouteVals,
IDictionary<string, object> htmlAttributes,
FormMethod method)
{
Mandate.ParameterNotNullOrEmpty(action, "action");
Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName");
var formAction = UmbracoContext.Current.OriginalRequestUrl.PathAndQuery;
return html.RenderForm(formAction, method, htmlAttributes, controllerName, action, area, additionalRouteVals);
}
/// <summary>
/// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin
/// </summary>
/// <param name="html"></param>
@@ -462,13 +719,9 @@ namespace Umbraco.Web
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName, string area,
object additionalRouteVals,
IDictionary<string, object> htmlAttributes)
{
Mandate.ParameterNotNullOrEmpty(action, "action");
Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName");
var formAction = UmbracoContext.Current.OriginalRequestUrl.PathAndQuery;
return html.RenderForm(formAction, FormMethod.Post, htmlAttributes, controllerName, action, area, additionalRouteVals);
}
{
return html.BeginUmbracoForm(action, controllerName, area, additionalRouteVals, htmlAttributes, FormMethod.Post);
}
/// <summary>
/// This renders out the form for us
@@ -496,7 +749,7 @@ namespace Umbraco.Web
{
//ensure that the multipart/form-data is added to the html attributes
if (!htmlAttributes.ContainsKey("enctype"))
if (htmlAttributes.ContainsKey("enctype") == false)
{
htmlAttributes.Add("enctype", "multipart/form-data");
}
@@ -507,7 +760,7 @@ namespace Umbraco.Web
tagBuilder.MergeAttribute("action", formAction);
// method is an explicit parameter, so it takes precedence over the htmlAttributes.
tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);
var traditionalJavascriptEnabled = htmlHelper.ViewContext.ClientValidationEnabled && !htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled;
var traditionalJavascriptEnabled = htmlHelper.ViewContext.ClientValidationEnabled && htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled == false;
if (traditionalJavascriptEnabled)
{
// forms must have an ID for client validation
@@ -516,7 +769,7 @@ namespace Umbraco.Web
htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
//new UmbracoForm:
var theForm = new UmbracoForm(htmlHelper.ViewContext, surfaceController, surfaceAction, area, additionalRouteVals);
var theForm = new UmbracoForm(htmlHelper.ViewContext, surfaceController, surfaceAction, area, method, additionalRouteVals);
if (traditionalJavascriptEnabled)
{

View File

@@ -109,23 +109,52 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Checks the request and query strings to see if it matches the definition of having a Surface controller
/// posted value, if so, then we return a PostedDataProxyInfo object with the correct information.
/// posted/get value, if so, then we return a PostedDataProxyInfo object with the correct information.
/// </summary>
/// <param name="requestContext"></param>
/// <returns></returns>
private static PostedDataProxyInfo GetPostedFormInfo(RequestContext requestContext)
{
if (requestContext.HttpContext.Request.RequestType != "POST")
return null;
private static PostedDataProxyInfo GetFormInfo(RequestContext requestContext)
{
//if it is a POST/GET then a value must be in the request
if ((requestContext.HttpContext.Request.RequestType == "POST" || requestContext.HttpContext.Request.RequestType == "GET")
&& requestContext.HttpContext.Request["ufprt"].IsNullOrWhiteSpace())
{
return null;
}
//this field will contain a base64 encoded version of the surface route vals
if (requestContext.HttpContext.Request["uformpostroutevals"].IsNullOrWhiteSpace())
return null;
string encodedVal;
switch (requestContext.HttpContext.Request.RequestType)
{
case "POST":
//get the value from the request.
//this field will contain an encrypted version of the surface route vals.
encodedVal = requestContext.HttpContext.Request["ufprt"];
break;
case "GET":
//get the value from the cookie based on the id sent as a query string.
var cookieId = "ufprt_" + requestContext.HttpContext.Request["ufprt"];
if (requestContext.HttpContext.Request.Cookies[cookieId] == null || requestContext.HttpContext.Request.Cookies[cookieId].Value.IsNullOrWhiteSpace())
{
LogHelper.Warn<RenderRouteHandler>("Umbraco cannot process the GET form action, could not find the required cookie value for cookie name " + cookieId);
//we cannot continue if there is no cookie value
return null;
}
var encodedVal = requestContext.HttpContext.Request["uformpostroutevals"];
var decryptedString = encodedVal.DecryptWithMachineKey();
var parsedQueryString = HttpUtility.ParseQueryString(decryptedString);
//we need to ensure the cookie is gone
var outgoingCookie = requestContext.HttpContext.Request.Cookies[cookieId];
outgoingCookie.Expires = DateTime.Now.AddDays(-1);
requestContext.HttpContext.Response.SetCookie(outgoingCookie);
//this field will contain an encrypted version of the surface route vals.
encodedVal = requestContext.HttpContext.Request.Cookies[cookieId].Value;
break;
default:
return null;
}
var decryptedString = encodedVal.DecryptWithMachineKey();
var parsedQueryString = HttpUtility.ParseQueryString(decryptedString);
var decodedParts = new Dictionary<string, string>();
foreach (var key in parsedQueryString.AllKeys)
@@ -336,7 +365,7 @@ namespace Umbraco.Web.Mvc
var routeDef = GetUmbracoRouteDefinition(requestContext, publishedContentRequest);
//Need to check for a special case if there is form data being posted back to an Umbraco URL
var postedInfo = GetPostedFormInfo(requestContext);
var postedInfo = GetFormInfo(requestContext);
if (postedInfo != null)
{
return HandlePostedValues(requestContext, postedInfo);