On my PageModel, I have a property that is of type ConcurrentDictionary<string, string>
and I want to bind that property. However, applying the [BindProperty]
attribute to that property doesn't work. The dictionary is populated with information about the PageModel itself, not the expected content of the dictionary.
Page:
@page
@model MyApp.Pages.MyPageModel
<h6>Dictionary</h6>
<dl>
@foreach (var key in Model.Dict.Keys)
{
<dt>@key</dt>
<dd>@Model.Dict[key]</dd>
}
</dl>
<h6>Concurrent Dictionary</h6>
<dl>
@foreach (var key in Model.ConcurrentDict.Keys)
{
<dt>@key</dt>
<dd>@Model.ConcurrentDict[key]</dd>
}
</dl>
<form method="post">
<input type="submit" value="submit" />
</form>
PageModel:
namespace MyApp.Pages;
using System.Collections.Concurrent;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
[AllowAnonymous]
public class MyPageModel : PageModel
{
[BindProperty]
public ConcurrentDictionary<string, string> ConcurrentDict { get; set; }
[BindProperty]
public Dictionary<string, string> Dict { get; set; }
public IActionResult OnGet()
{
ConcurrentDict = new()
{
["concurrent_foo"] = "concurrent_bar"
};
Dict = new()
{
["foo"] = "bar"
};
return this.Page();
}
public IActionResult OnPost()
{
return this.Page();
}
}
After a GET request:
After a POST request (form submission):
Anyone have an idea what's going on here? Any known work-around? Obviously .NET's built-in model binding doesn't play nicely with dictionaries... But I sure would like it to.
CodePudding user response:
You need to pass the values of dictionaries when submitting the form.If you don't want to show the inputs,add hidden
:
<form method="post">
@for (var i = 0; i < Model.ConcurrentDict.Count; i )
{
<input name="ConcurrentDict[@i].Key" value="@Model.ConcurrentDict.ElementAt(i).Key" hidden />
<input name="ConcurrentDict[@i].Value" value="@Model.ConcurrentDict.ElementAt(i).Value" hidden />
}
@for (var i = 0; i < Model.Dict.Count; i )
{
<input name="Dict[@i].Key" value="@Model.Dict.ElementAt(i).Key" hidden />
<input name="Dict[@i].Value" value="@Model.Dict.ElementAt(i).Value" hidden />
}
<input type="submit" value="submit" />
</form>