escaped query string
1ea1370be14758ba59b9366a8fa15b9941094766
6 files changed
src/Mvc.ModelBinding.MultiParameter.Testing/Controllers/ComplexController.cssrc/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/Default.jssrc/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/index.htmlsrc/Mvc.ModelBinding.MultiParameter/CookyValueProviderFactory.cssrc/Mvc.ModelBinding.MultiParameter/Helper.cssrc/Mvc.ModelBinding.MultiParameter/QueryStringValueProviderFactory.cs
diff --git a/src/Mvc.ModelBinding.MultiParameter.Testing/Controllers/ComplexController.cs b/src/Mvc.ModelBinding.MultiParameter.Testing/Controllers/ComplexController.cs
index 3ee5661..7ac80f7 100644
--- a/src/Mvc.ModelBinding.MultiParameter.Testing/Controllers/ComplexController.cs
+++ b/src/Mvc.ModelBinding.MultiParameter.Testing/Controllers/ComplexController.cs
@@ -30,6 +30,14 @@ public class ApiController : ControllerBase
});
}
+ [HttpGet("~/api/QueryString")]
+ public IActionResult QueryString(string question)
+ {
+ return Ok(new
+ {
+ Value = question
+ });
+ }
[HttpGet("index")]
// 1.0
@@ -580,4 +588,15 @@ public class ApiController : ControllerBase
Value = mycookie
});
}
+
+ [HttpPost("~/api/PostIt")]
+ public IActionResult PostIt(string Name, int Age)
+ {
+
+ return Ok(new
+ {
+ Name,
+ Age
+ });
+ }
}
diff --git a/src/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/Default.js b/src/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/Default.js
index 5683430..339f68a 100644
--- a/src/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/Default.js
+++ b/src/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/Default.js
@@ -1,21 +1,21 @@
-onReady(() =>
+const result = $id('Result');
+var r, result1, result2;
+
+onReady(() =>
{
PageEvents();
Init();
-
});
-var result;
-
function PageEvents()
{
document.on("click", async function (e)
{
if (e.target.id && typeof window[e.target.id] === "function")
{
- const result = window[e.target.id].call(e, e);
- if (result instanceof Promise)
- await result;
+ const func = window[e.target.id].call(e, e);
+ if (func instanceof Promise)
+ await func;
}
});
@@ -27,13 +27,9 @@ function PageEvents()
function Init()
{
- result = $id('Result');
netproxy("./api/HelloWorld"); // Makes session (and cookie)
}
-var r;
-var result1,result2;
-
function C(s, jscript)
{
if (eval(jscript))
@@ -52,6 +48,15 @@ async function UnitTest()
C("Cookies", "r.Value == '1234'");
r = await netproxyasync("./api/GetHeader");
C("Headers (Accept)", "r.Value == '*/*'");
+ r = await netproxyasync("./api/QueryString?question=answer");
+ C("QueryString", "r.Value == 'answer'");
+
+ var formData = new FormData();
+ formData.append("Name", "Alphons");
+ formData.append("Age", "25")
+ r = await netproxyasync("/api/PostIt", formData);
+ C("Post Form Data", "r.Name == 'Alphons' && r.Age ==25");
+
r = await netproxyasync("./api/SimpleString1", user);
C("SimpleString1", "r.user == 'alphons'");
r = await netproxyasync("./api/SimpleString2", user);
@@ -61,6 +66,9 @@ async function UnitTest()
r = await netproxyasync("./api/SimpleString4", { model: { user: 'alphons' } });
C("SimpleString4", "r.user == 'alphons'");
+ r = await netproxyasync("./api/PostEnumAsString", { status: 'Active' });
+ C("PostEnumAsString", "r.Status == 'Active' && r.Value == 1");
+
var users = { "users": ["admins", "editors", null, "sisters"] };
r = await netproxyasync("./api/ArrayOfStrings1", users);
@@ -270,14 +278,14 @@ function ProgressHandler(event)
var total = event.total;
if (event.lengthComputable)
percent = Math.ceil(position / total * 100);
- $id("Result").innerText = "Uploading " + percent + "%";
+ result.innerText = "Uploading " + percent + "%";
}
function StartUpload(e)
{
var file = e.target.files[0];
- $id("Result").innerText = 'Uploading';
+ result.innerText = 'Uploading';
var formData = new FormData();
@@ -286,13 +294,13 @@ function StartUpload(e)
netproxy("/api/Upload", formData, function ()
{
- $id("Result").innerText = 'Ready Length:' + this.Length + " ExtraValue:" + this.Form1;
+ result.innerText = 'Ready Length:' + this.Length + " ExtraValue:" + this.Form1;
}, window.NetProxyErrorHandler, ProgressHandler);
}
async function MultiBinderTest()
{
- $id("Result").innerText = '';
+ result.innerText = '';
result1 = await netproxyasync("./api/DemoProposal/two?SomeParameter3=three&SomeParameter6=six",
{
"SomeParameter4": // Now the beast has a name
@@ -308,7 +316,7 @@ async function MultiBinderTest()
"SomeParameter5": "five" // double binder
});
- $id("Result").innerText = 'some alias: ' + result1.SomeParameter4.Users[0][0].Alias[1];
+ result.innerText = 'some alias: ' + result1.SomeParameter4.Users[0][0].Alias[1];
result2 = await netproxyasync("./api/DemoProposal2/two?SomeParameter3=three&SomeParameter6=six",
{
@@ -325,26 +333,17 @@ async function MultiBinderTest()
"SomeParameter5": "five" // double binder
});
- $id("Result").innerText += ' other alias: ' + result2.SomeParameter4.Users[0][0].Alias[2];
+ result.innerText += ' other alias: ' + result2.SomeParameter4.Users[0][0].Alias[2];
}
-
-async function PostEnumAsString()
+async function PostIt()
{
- var result = await netproxyasync("./api/PostEnumAsString", { status: 'Active' });
-
- $id("Result").innerText = ' status:' + result.Status + ' value:' + result.Value;
-}
+ var formData = new FormData();
-async function WriteCookie()
-{
- await netproxyasync("./api/WriteCookie", { value: 'This is a cookie value' });
-}
+ formData.append("Name", "Alphons");
+ formData.append("Age", "25")
-async function GetCookie()
-{
- var result = await netproxyasync("./api/GetCookie");
+ var r = netproxyasync("/api/PostIt", formData);
- $id("Result").innerText = "value from cookie is: " + result.Value;
-}
+}
\ No newline at end of file
diff --git a/src/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/index.html b/src/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/index.html
index c56bc07..f4e2163 100644
--- a/src/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/index.html
+++ b/src/Mvc.ModelBinding.MultiParameter.Testing/wwwroot/index.html
@@ -7,8 +7,8 @@
<!-- nugetpackage netproxy -->
<link href="css/netproxyspinner.css" rel="stylesheet" />
- <script src="scripts/macros.js" defer></script>
- <script src="scripts/netproxy2.js?1" defer></script>
+ <script src="scripts/macros.js?1" defer></script>
+ <script src="scripts/netproxy.js?1" defer></script>
<link href="Default.css" rel="stylesheet" />
<link href="Ui.css" rel="stylesheet" />
@@ -29,11 +29,7 @@
<div><span id="MultiBinderTest" class="ui-btn">MultiBinderTest</span></div>
- <div><span id="PostEnumAsString" class="ui-btn">Post Enum As String</span></div>
-
- <div><span id="WriteCookie" class="ui-btn">WriteCookie</span></div>
-
- <div><span id="GetCookie" class="ui-btn">GetCookie</span></div>
+ <div><span id="PostIt" class="ui-btn">PostIt</span></div>
</body>
</html>
diff --git a/src/Mvc.ModelBinding.MultiParameter/CookyValueProviderFactory.cs b/src/Mvc.ModelBinding.MultiParameter/CookyValueProviderFactory.cs
index c367079..7847074 100644
--- a/src/Mvc.ModelBinding.MultiParameter/CookyValueProviderFactory.cs
+++ b/src/Mvc.ModelBinding.MultiParameter/CookyValueProviderFactory.cs
@@ -4,12 +4,12 @@
// Version: 1.2 Date: 2022-04-10
// Version: 1.3 Date: 2024-11-23
+using Mvc.ModelBinding.MultiParameter;
using System.Text.Json;
-using System.Text.RegularExpressions;
namespace Microsoft.AspNetCore.Mvc.ModelBinding.MultiParameter;
-public partial class CookyValueProviderFactory : IValueProviderFactory
+public class CookyValueProviderFactory : IValueProviderFactory
{
private readonly JsonSerializerOptions? jsonSerializerOptions;
public CookyValueProviderFactory(JsonSerializerOptions? Options)
@@ -21,30 +21,6 @@ public partial class CookyValueProviderFactory : IValueProviderFactory
this.jsonSerializerOptions = null;
}
- [GeneratedRegex("[\"\\\\\b\f\n\r\t]")]
- private static partial Regex MyRegex();
- private static string EscapeForJson(string value)
- {
- if (string.IsNullOrEmpty(value))
- {
- return string.Empty;
- }
-
- return MyRegex().Replace(value, match =>
- {
- return match.Value switch
- {
- "\"" => "\\\"",
- "\\" => "\\\\",
- "\b" => "\\b",
- "\f" => "\\f",
- "\n" => "\\n",
- "\r" => "\\r",
- "\t" => "\\t",
- _ => match.Value
- };
- });
- }
public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
{
@@ -55,7 +31,7 @@ public partial class CookyValueProviderFactory : IValueProviderFactory
try
{
var cookieList = cookies
- .Select(cookie => $"\"{EscapeForJson(cookie.Key)}\": \"{EscapeForJson(cookie.Value)}\"")
+ .Select(cookie => $"\"{Helper.EscapeForJson(cookie.Key)}\": \"{Helper.EscapeForJson(cookie.Value)}\"")
.ToArray();
var json = $"{{{string.Join(',', cookieList)}}}";
diff --git a/src/Mvc.ModelBinding.MultiParameter/Helper.cs b/src/Mvc.ModelBinding.MultiParameter/Helper.cs
new file mode 100644
index 0000000..24c0d3d
--- /dev/null
+++ b/src/Mvc.ModelBinding.MultiParameter/Helper.cs
@@ -0,0 +1,29 @@
+using System.Text.RegularExpressions;
+
+namespace Mvc.ModelBinding.MultiParameter;
+
+internal partial class Helper
+{
+ [GeneratedRegex("[\"\\\\\b\f\n\r\t]")]
+ private static partial Regex MyRegex();
+ public static string EscapeForJson(string? value)
+ {
+ if (string.IsNullOrEmpty(value))
+ return string.Empty;
+
+ return MyRegex().Replace(value, match =>
+ {
+ return match.Value switch
+ {
+ "\"" => "\\\"",
+ "\\" => "\\\\",
+ "\b" => "\\b",
+ "\f" => "\\f",
+ "\n" => "\\n",
+ "\r" => "\\r",
+ "\t" => "\\t",
+ _ => match.Value
+ };
+ });
+ }
+}
diff --git a/src/Mvc.ModelBinding.MultiParameter/QueryStringValueProviderFactory.cs b/src/Mvc.ModelBinding.MultiParameter/QueryStringValueProviderFactory.cs
index 667b547..5b77e26 100644
--- a/src/Mvc.ModelBinding.MultiParameter/QueryStringValueProviderFactory.cs
+++ b/src/Mvc.ModelBinding.MultiParameter/QueryStringValueProviderFactory.cs
@@ -7,6 +7,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using Mvc.ModelBinding.MultiParameter;
+using System.Net;
using System.Text.Json;
namespace Microsoft.AspNetCore.Mvc.ModelBinding.MultiParameter;
@@ -18,38 +20,40 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.MultiParameter;
/// </summary>
public class QueryStringValueProviderFactory : IValueProviderFactory
{
- private readonly JsonSerializerOptions? jsonSerializerOptions;
- public QueryStringValueProviderFactory(JsonSerializerOptions? Options) : base()
- {
- this.jsonSerializerOptions = Options;
- }
-
- public QueryStringValueProviderFactory()
- {
- this.jsonSerializerOptions = null;
- }
-
- /// <inheritdoc />
- public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
- {
+ private readonly JsonSerializerOptions? jsonSerializerOptions;
+ public QueryStringValueProviderFactory(JsonSerializerOptions? Options) : base()
+ {
+ this.jsonSerializerOptions = Options;
+ }
+
+ public QueryStringValueProviderFactory()
+ {
+ this.jsonSerializerOptions = null;
+ }
+
+ /// <inheritdoc />
+ public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
+ {
ArgumentNullException.ThrowIfNull(context);
var query = context.ActionContext.HttpContext.Request.Query;
- if (query != null && query.Count > 0)
- {
- var list = query.Select(x => $"\"{x.Key}\": \"{x.Value}\"").ToArray();
- var json = $"{{{string.Join(',', list)}}}";
- var jsonDocument = JsonDocument.Parse(json, options: default);
-
- var valueProvider = new GenericValueProvider(
- BindingSource.Query,
- jsonDocument,
- null,
- this.jsonSerializerOptions);
-
- context.ValueProviders.Add(valueProvider);
- }
-
- return Task.CompletedTask;
- }
+ if (query != null && query.Count > 0)
+ {
+ var list = query
+ .Select(x => $"\"{Helper.EscapeForJson(x.Key)}\": \"{Helper.EscapeForJson(x.Value)}\"")
+ .ToArray();
+ var json = $"{{{string.Join(',', list)}}}";
+ var jsonDocument = JsonDocument.Parse(json, options: default);
+
+ var valueProvider = new GenericValueProvider(
+ BindingSource.Query,
+ jsonDocument,
+ null,
+ this.jsonSerializerOptions);
+
+ context.ValueProviders.Add(valueProvider);
+ }
+
+ return Task.CompletedTask;
+ }
}