将 HierarchyId 与 ASP.NET 核心一起使用会导致发送 post 请求时出错?

Using HierarchyId with ASP.NET Core causes error in send post request?

我想使用 HierarchyId 类型创建国家/地区

我创建了一个 Country 模型 class 具有以下属性:

namespace DotNetCore5Crud.Models
{
    public class Country
    {
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        public HierarchyId parentId { get; set; }
    }
}

然后我创建了一个工作正常的 Index 视图:

@model IEnumerable<Category>

<partial name="_addCategory" model="new Category()" />
@{
    if (!Model.Any())
    {
        <div class="alert alert-warning" role="alert">
            there Is no Categories
        </div>
    }
    else
    {
        <div class="container">
            <table class="table table-sm table-hover table-striped">
                <thead>
                    <tr class="bg-primary text-white font-weight-bold">
                        <th>id</th>
                        <th>Name</th>
                        <th>HierarchyId</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model)
                    {
                        <tr>
                            <td>@item.Id</td>
                            <td>@item.Name</td>
                            <td>@item.hierarchyId</td>
                        </tr>
                    }
                </tbody>
            </table>
        </div>
    }
}

然后,我将部分视图注入 AddCountry:

@model Category
    <!-- Button trigger modal -->
    <button type="button" class="btn btn-sm mb-2 btn-primary" data-toggle="modal" data-target="#exampleModalCenter">
        <i class="bi bi-plus-circle"></i> Add Category
    </button>

    <!-- Modal -->
    <div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
        <form method="post" asp-action="Create" asp-controller="Categories">
            <div class="modal-dialog modal-dialog-centered" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLongTitle"><i class="bi bi-plus-circle"></i> Add Category</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <div class="form-group">
                            <label class="text-muted" asp-for="Name"></label>
                            <input type="text" asp-for="Name" class="form-control" />
                            <span class="text-danger" asp-validation-for="Name"></span>
                        </div>
                        <div class="form-control">
                            <label class="text-muted" asp-for="hierarchyId"></label>
                            <select class="form-control" asp-for="hierarchyId" id="hierarchyId">
                                @foreach (var item in ViewBag.AllCAT)
                                {
                                    <option value="@item.Id">@item.Name</option>
                                }
                            </select>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Cancel</button>
                        <button type="submit" class="btn btn-sm btn-primary">Save</button>
                    </div>
                </div>
            </div>
        </form>
    </div>

最后,当我从视图发送数据时,名称发送正确但 HierarchyId 列为空,如下所示:

enter image description here

不知道为什么会这样。。。找了很多都没有找到解释

如果你能告诉我为什么会这样,我将不胜感激。

模型绑定无法自动绑定 HierarchyId 类型,因此 parentId 将在您的控制器中显示为“null”,您可以使用 Request.Form["parentId"] 手动获取此 属性。

<select>通过<option>中的'value'属性传递值。在你的代码中,Id是int,它与parentId的类型不匹配,所以我替换了它与 parentId.

_addCategory.cshtml

@model Country
    <!-- Button trigger modal -->
    <button type="button" class="btn btn-sm mb-2 btn-primary" data-toggle="modal" data-target="#exampleModalCenter">
        <i class="bi bi-plus-circle"></i> Add Category
    </button>

    <!-- Modal -->
    <div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
        <form method="post" asp-action="Create" asp-controller="Home">
            <div class="modal-dialog modal-dialog-centered" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLongTitle"><i class="bi bi-plus-circle"></i> Add Category</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <div class="form-group">
                            <label class="text-muted" asp-for="Name"></label>
                            <input type="text" asp-for="Name" class="form-control" />
                            <span class="text-danger" asp-validation-for="Name"></span>
                        </div>
                        <div class="form-control">
                            <label class="text-muted" asp-for="parentId"></label>
                            <select class="form-control" asp-for="parentId" id="hierarchyId">
                                @foreach (var item in ViewBag.Country)
                                {
                                        <!--change here...-->
                                    <option value="@item.parentId">@item.Name</option>
                                }
                            </select>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Cancel</button>
                        <button type="submit" class="btn btn-sm btn-primary">Save</button>
                    </div>
                </div>
            </div>
        </form>
    </div>

控制器

public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IActionResult Create() {
            //For the convenience of testing, I hard-coded here
            ViewBag.Country = new List<Country>()
            {
                new Country(){ Id=1,Name= " USA ",parentId = HierarchyId.Parse("/1/") },
                new Country(){ Id=2,Name= "Canada",parentId =HierarchyId.Parse("/2/") },
                new Country(){ Id=3,Name= "China",parentId = HierarchyId.Parse("/3/") },
                new Country(){Id=4,Name= "Japan" ,parentId = HierarchyId.Parse("/4/")}
            };
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<object> Create(Country country) 
        {
            //Model Binding can’t bind HierarchyId automatically,
            //so I use ‘Request.Form’ to accept parentId, and convent parentId to string type and use PId to accept it, Then I convert PId to HierarchyId and Assign this value to parentId
            var PId = Request.Form["parentId"].ToString();
            country.parentId =  HierarchyId.Parse(PId);
            //do your stuff....
            return View();
        }
    }

You can see the result here