diff --git a/src/Umbraco.Web/Trees/ApplicationTreeController.cs b/src/Umbraco.Web/Trees/ApplicationTreeController.cs
index 31272363ae..eedd840a3e 100644
--- a/src/Umbraco.Web/Trees/ApplicationTreeController.cs
+++ b/src/Umbraco.Web/Trees/ApplicationTreeController.cs
@@ -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
///
/// An optional bool (defaults to true), if set to false it will also load uninitialized trees
///
- [HttpQueryStringFilter("queryStrings")]
- public async Task GetApplicationTrees(string application, string tree, FormDataCollection queryStrings, bool onlyInitialized = true)
+ public async Task GetApplicationTrees(string application, string tree, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings, bool onlyInitialized = true)
{
application = application.CleanForXss();
diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
index 1a0a135bac..af38e21546 100644
--- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
@@ -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
///
///
///
- [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;
diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs
index 3ec12aa2b5..fac2552f99 100644
--- a/src/Umbraco.Web/Trees/MemberTreeController.cs
+++ b/src/Umbraco.Web/Trees/MemberTreeController.cs
@@ -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
///
///
///
- [HttpQueryStringFilter("queryStrings")]
- public TreeNode GetTreeNode(string id, FormDataCollection queryStrings)
+ public TreeNode GetTreeNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
var node = GetSingleTreeNode(id, queryStrings);
diff --git a/src/Umbraco.Web/Trees/TreeControllerBase.cs b/src/Umbraco.Web/Trees/TreeControllerBase.cs
index b0aacc67c6..98eb2ec8bc 100644
--- a/src/Umbraco.Web/Trees/TreeControllerBase.cs
+++ b/src/Umbraco.Web/Trees/TreeControllerBase.cs
@@ -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.
///
- protected abstract TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings);
+ protected abstract TreeNodeCollection GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings);
///
/// Returns the menu structure for the node
@@ -51,7 +52,7 @@ namespace Umbraco.Web.Trees
///
///
///
- protected abstract MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings);
+ protected abstract MenuItemCollection GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings);
///
/// The name to display on the root node
@@ -68,8 +69,7 @@ namespace Umbraco.Web.Trees
///
///
///
- [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.
///
- [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
///
///
///
- [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);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 036cb96b50..87e42a77b5 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -840,6 +840,7 @@
+
diff --git a/src/Umbraco.Web/WebApi/Filters/HttpQueryStringFilterAttribute.cs b/src/Umbraco.Web/WebApi/Filters/HttpQueryStringFilterAttribute.cs
index 5cdf7a7e94..5998d54c57 100644
--- a/src/Umbraco.Web/WebApi/Filters/HttpQueryStringFilterAttribute.cs
+++ b/src/Umbraco.Web/WebApi/Filters/HttpQueryStringFilterAttribute.cs
@@ -6,13 +6,7 @@ using System.Web.Http.Filters;
namespace Umbraco.Web.WebApi.Filters
{
- ///
- /// Allows an Action to execute with an arbitrary number of QueryStrings
- ///
- ///
- /// 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
- ///
+ [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);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/WebApi/Filters/HttpQueryStringModelBinder.cs b/src/Umbraco.Web/WebApi/Filters/HttpQueryStringModelBinder.cs
new file mode 100644
index 0000000000..6ffbb239f8
--- /dev/null
+++ b/src/Umbraco.Web/WebApi/Filters/HttpQueryStringModelBinder.cs
@@ -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
+{
+ ///
+ /// Allows an Action to execute with an arbitrary number of QueryStrings
+ ///
+ ///
+ /// 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
+ ///
+ 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> queryStrings)
+ {
+ var formData = new FormDataCollection(queryStrings);
+ bindingContext.Model = formData;
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file