Merge pull request #3851 from umbraco/temp-fix-formdatacollection-3796

Fixes binding of FormDataCollection for GET requests which fixes the …
This commit is contained in:
Shannon Deminick
2019-03-05 13:39:37 +10:00
committed by GitHub
7 changed files with 48 additions and 23 deletions

View File

@@ -7,6 +7,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web.Models.Trees;
@@ -31,8 +32,7 @@ namespace Umbraco.Web.Trees
/// <param name="queryStrings"></param>
/// <param name="onlyInitialized">An optional bool (defaults to true), if set to false it will also load uninitialized trees</param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public async Task<SectionRootNode> GetApplicationTrees(string application, string tree, FormDataCollection queryStrings, bool onlyInitialized = true)
public async Task<SectionRootNode> GetApplicationTrees(string application, string tree, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings, bool onlyInitialized = true)
{
application = application.CleanForXss();

View File

@@ -15,6 +15,7 @@ using Umbraco.Web.WebApi.Filters;
using umbraco;
using umbraco.BusinessLogic.Actions;
using System.Globalization;
using System.Web.Http.ModelBinding;
using Umbraco.Core.Services;
namespace Umbraco.Web.Trees
@@ -30,8 +31,7 @@ namespace Umbraco.Web.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public TreeNode GetTreeNode(string id, FormDataCollection queryStrings)
public TreeNode GetTreeNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
int asInt;
Guid asGuid = Guid.Empty;

View File

@@ -6,6 +6,7 @@ using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Models;
@@ -53,8 +54,7 @@ namespace Umbraco.Web.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public TreeNode GetTreeNode(string id, FormDataCollection queryStrings)
public TreeNode GetTreeNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
var node = GetSingleTreeNode(id, queryStrings);

View File

@@ -2,6 +2,7 @@
using System.Globalization;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http.ModelBinding;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Web.Models.Trees;
@@ -43,7 +44,7 @@ namespace Umbraco.Web.Trees
/// We are allowing an arbitrary number of query strings to be pased in so that developers are able to persist custom data from the front-end
/// to the back end to be used in the query for model data.
/// </remarks>
protected abstract TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings);
protected abstract TreeNodeCollection GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings);
/// <summary>
/// Returns the menu structure for the node
@@ -51,7 +52,7 @@ namespace Umbraco.Web.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
protected abstract MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings);
protected abstract MenuItemCollection GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings);
/// <summary>
/// The name to display on the root node
@@ -68,8 +69,7 @@ namespace Umbraco.Web.Trees
/// </summary>
/// <param name="queryStrings"></param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public TreeNode GetRootNode(FormDataCollection queryStrings)
public TreeNode GetRootNode([ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
if (queryStrings == null) queryStrings = new FormDataCollection("");
var node = CreateRootNode(queryStrings);
@@ -108,8 +108,7 @@ namespace Umbraco.Web.Trees
/// We are allowing an arbitrary number of query strings to be pased in so that developers are able to persist custom data from the front-end
/// to the back end to be used in the query for model data.
/// </remarks>
[HttpQueryStringFilter("queryStrings")]
public TreeNodeCollection GetNodes(string id, FormDataCollection queryStrings)
public TreeNodeCollection GetNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
if (queryStrings == null) queryStrings = new FormDataCollection("");
var nodes = GetTreeNodes(id, queryStrings);
@@ -140,8 +139,7 @@ namespace Umbraco.Web.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public MenuItemCollection GetMenu(string id, FormDataCollection queryStrings)
public MenuItemCollection GetMenu(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
if (queryStrings == null) queryStrings = new FormDataCollection("");
var menu = GetMenuForNode(id, queryStrings);
@@ -390,4 +388,4 @@ namespace Umbraco.Web.Trees
if (handler != null) handler(instance, e);
}
}
}
}

View File

@@ -840,6 +840,7 @@
<Compile Include="WebApi\Filters\EnableOverrideAuthorizationAttribute.cs" />
<Compile Include="WebApi\Filters\FeatureAuthorizeAttribute.cs" />
<Compile Include="WebApi\Filters\FilterGrouping.cs" />
<Compile Include="WebApi\Filters\HttpQueryStringModelBinder.cs" />
<Compile Include="WebApi\Filters\LegacyTreeAuthorizeAttribute.cs" />
<Compile Include="WebApi\Filters\OutgoingEditorModelEventAttribute.cs" />
<Compile Include="WebApi\Filters\OutgoingNoHyphenGuidFormatAttribute.cs" />

View File

@@ -6,13 +6,7 @@ using System.Web.Http.Filters;
namespace Umbraco.Web.WebApi.Filters
{
/// <summary>
/// Allows an Action to execute with an arbitrary number of QueryStrings
/// </summary>
/// <remarks>
/// Just like you can POST an arbitrary number of parameters to an Action, you can't GET an arbitrary number
/// but this will allow you to do it
/// </remarks>
[Obsolete("Use HttpQueryStringModelBinder to model bind FormDataCollection in a GET request")]
public sealed class HttpQueryStringFilterAttribute : ActionFilterAttribute
{
public string ParameterName { get; private set; }
@@ -40,4 +34,4 @@ namespace Umbraco.Web.WebApi.Filters
base.OnActionExecuting(actionContext);
}
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Net.Http.Formatting;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
namespace Umbraco.Web.WebApi.Filters
{
/// <summary>
/// Allows an Action to execute with an arbitrary number of QueryStrings
/// </summary>
/// <remarks>
/// Just like you can POST an arbitrary number of parameters to an Action, you can't GET an arbitrary number
/// but this will allow you to do it
/// </remarks>
public sealed class HttpQueryStringModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
//get the query strings from the request properties
if (actionContext.Request.Properties.ContainsKey("MS_QueryNameValuePairs"))
{
if (actionContext.Request.Properties["MS_QueryNameValuePairs"] is IEnumerable<KeyValuePair<string, string>> queryStrings)
{
var formData = new FormDataCollection(queryStrings);
bindingContext.Model = formData;
return true;
}
}
return false;
}
}
}