Skip to content

Commit 1f8f848

Browse files
Add custom ModelBinder to ensure query parameters of type string are bound as empty strings instead of null (#1098)
1 parent f8a907d commit 1f8f848

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

dotnet/src/dotnetcore/GxClasses.Web/Middleware/GXRestServices.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
using Microsoft.AspNetCore.Http;
1515
using Microsoft.AspNetCore.Mvc;
1616
using Microsoft.AspNetCore.Mvc.Filters;
17+
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
18+
using Microsoft.AspNetCore.Mvc.ModelBinding;
19+
using System.Threading.Tasks;
1720

1821

1922
namespace GeneXus.Utils
@@ -29,6 +32,36 @@ public void OnActionExecuting(ActionExecutingContext context)
2932
(context.Controller as GxRestService).Initialize();
3033
}
3134
}
35+
36+
public class QueryStringModelBinderProvider : IModelBinderProvider
37+
{
38+
public IModelBinder GetBinder(ModelBinderProviderContext context)
39+
{
40+
if (context.BindingInfo.BindingSource == BindingSource.Query &&
41+
context.Metadata.ModelType == typeof(string))
42+
{
43+
return new BinderTypeModelBinder(typeof(CustomQueryStringBinder));
44+
}
45+
return null;
46+
}
47+
}
48+
public class CustomQueryStringBinder : IModelBinder
49+
{
50+
public Task BindModelAsync(ModelBindingContext bindingContext)
51+
{
52+
if (!bindingContext.BindingSource.CanAcceptDataFrom(BindingSource.Query))
53+
{
54+
return Task.CompletedTask;
55+
}
56+
if (bindingContext.ModelType != typeof(string))
57+
{
58+
return Task.CompletedTask;
59+
}
60+
string value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).FirstValue;
61+
bindingContext.Result = ModelBindingResult.Success(value ?? string.Empty);
62+
return Task.CompletedTask;
63+
}
64+
}
3265
[TypeFilter(typeof(CustomActionFilter))]
3366
public class GxRestService : ControllerBase
3467
{

dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,13 @@ public void ConfigureServices(IServiceCollection services)
268268
private void RegisterControllerAssemblies(IMvcBuilder mvcBuilder)
269269
{
270270

271-
if (RestAPIHelpers.ServiceAsController() && !string.IsNullOrEmpty(VirtualPath))
271+
if (RestAPIHelpers.ServiceAsController())
272272
{
273-
mvcBuilder.AddMvcOptions(options => options.Conventions.Add(new SetRoutePrefix(new RouteAttribute(VirtualPath))));
273+
mvcBuilder.AddMvcOptions(options => options.ModelBinderProviders.Insert(0, new QueryStringModelBinderProvider()));
274+
if (!string.IsNullOrEmpty(VirtualPath))
275+
{
276+
mvcBuilder.AddMvcOptions(options => options.Conventions.Add(new SetRoutePrefix(new RouteAttribute(VirtualPath))));
277+
}
274278
}
275279

276280
if (RestAPIHelpers.JsonSerializerCaseSensitive())

0 commit comments

Comments
 (0)