web-dev-qa-db-ja.com

ASP.NET CoreRazorPagesで複雑なリストをバインドするにはどうすればよいですか

ASP.NET Core RazorPagesは初めてです。 POSTを介してページからリスト<>を取得しようとしています。プリミティブデータ型をバインドしても、問題は発生しませんでした。しかし、自分のページからリストを含むサーバーにデータを渡したい場合、問題が発生しました。サーバーからクライアントにデータを渡すことはできましたが、戻すことはできませんでした。

これは私のコードからの抜粋です:

RazorPage:

<form method="post">
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Positions[0].Number)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Positions[0].IsSelected)
                </th>
            </tr>
        </thead>
        <tbody>
            @if (!(Model.Positions is null))
            {
                @foreach (var item in Model.Positions)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Number)
                        </td>
                        <td>
                            @Html.CheckBoxFor(modelItem => item.IsSelected)
                        </td>
                    </tr>
                }
            }
        </tbody>
    </table>
    <input type="submit" />

バックエンドC#ファイル:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Project.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;

namespace Project.Pages
{
    public class TestModel : PageModel
    {
        private readonly DBContext _context;


        [FromRoute]
        public int? Id { get; set; }
        public List<SelectListItem> CustomerOrder { get; set; } = new List<SelectListItem>();
        [BindProperty]
        public string SelectedNumber { get; set; }
        [BindProperty]
        public List<Position> Positions { get; set; }
        public TestModel(Project.Models.DBContext context)
        {
            _context = context;
        }
        public void OnGet()
        {
            if (!(Id is null))
            {
                _context.CustomerOrder.Select(co => co.OrderNumber).Distinct().ToList().ForEach(y => CustomerOrder.Add(new SelectListItem(text: y, value: y)));
            }
        }

        public async Task OnPostAsync()
        {
            if (!(SelectedNumber is null))
            {
                string s = $@"
                select * from Table1 xyz where xyz.Column1 in (
                    SELECT distinct Column1
                    FROM Table1
                    where value = '" + SelectedNumber + "') and xyz.name = 'SLLZ'";

                var res = await _context.Table1.FromSql(s).Select(x => x.ValueDescription).Distinct().OrderBy(x => x).ToListAsync();

                Positions = new List<Position>();
                foreach (var item in res)
                {
                    Positions.Add(new Position { Number = item });
                }


            }
            _context.CustomerOrder.Select(co => co.OrderNumber).Distinct().ToList().ForEach(y => CustomerOrder.Add(new SelectListItem(text: y, value: y)));

        }
    }
    public class Position
    {
        public string Number { get; set; }
        public bool IsSelected { get; set; }
    }
}

OnPost-Methodの先頭にブレークポイントを設定すると、チェックボックスへのユーザーの入力に関連するIsSelected-Propertyがリストに入力されると思いますが、そうではありません。

3
Jonas

複雑なオブジェクトバインディングの鍵は、角括弧内のシーケンシャルインデックスがフォームフィールドの名前属性に追加されるようにすることです。例:[0].IsSelectedまたはPositions[0].IsSelectedあなたの場合。 forループとタグヘルパーを使用すると、正しいHTMLを非常に簡単に出力できます。

プリンシパルの詳細については、こちらをご覧ください: https://www.learnrazorpages.com/razor-pages/model-binding#binding-complex-collections 。そうすれば、それをアプリケーションに適用できるはずです。

3
Mike Brind