Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
94 views
in Technique[技术] by (71.8m points)

c# - .Net Core -Prepopulating foreign(parent) key in child record from parent results in error in navigation after ‘create child record’ save

Hi I have a parent child relationship between two entities- PositionSummary and PositionDetail.

Here are the models.

    using System;
using System.Collections.Generic;

namespace ThePositionerRazor2.Models
{
    public partial class Possummary
    {
        public Possummary()
        {
            Posdetail = new HashSet<Posdetail>();
        }

        public int PositionId { get; set; }
        public string PositionNbr { get; set; }
        public string WorkTitle { get; set; }
        public string Purpose { get; set; }
        public double? JobValue { get; set; }
        public double? TimeTotal { get; set; }
        public double? Fte { get; set; }
        public double? Salary { get; set; }
        public DateTime? Lastupdated { get; set; }
        public string JobFamily { get; set; }
        public int? DescriptionTypeId { get; set; }

        public virtual Descriptiontype DescriptionType { get; set; }
        public virtual ICollection<Posdetail> Posdetail { get; set; }
    }
}

and

    using System;
using System.Collections.Generic;

namespace ThePositionerRazor2.Models
{
    public partial class Posdetail
    {
        public int PosdetailId { get; set; }
        public int PositionId { get; set; }
        public int Workitem { get; set; }
        public int? TimeSpent { get; set; }
        public int? ImportanceId { get; set; }
        public double? TimeNrmz { get; set; }
        public int? Knowdepth { get; set; }
        public int? Need { get; set; }
        public int? TimeCalc { get; set; }
        public double? Postskval { get; set; }
        public double? Ftetime { get; set; }
        public double? Ftesal { get; set; }
        public DateTime Lastupdated { get; set; }

        public virtual Imp Importance { get; set; }
        public virtual Knowdep KnowdepthNavigation { get; set; }
        public virtual Possummary Position { get; set; }
        public virtual Timescale TimeSpentNavigation { get; set; }
        public virtual Workhier WorkitemNavigation { get; set; }
    }
}

The Parent successfully navigates to the selected child records list. On the child list page I am navigating to a child create page with a parameter ( the parent foreign key) because I don’t want to enter the parent foreign key each time. The create page OnPostAsync procedure returns to the child list page after the save (ie standard scaffolding code). My code compiles without error. When I hit the create button the create page the record DOES save it in the SQL server database BUT the navigation back to the child list page results in an error.

The error is: ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') ThePositionerRazor2.Pages.PositionDetail.Pages_PositionDetail_Index.ExecuteAsync() in Index.cshtml + 14. Create New

The idea would be that upon return to child list- that the return would be successful and that if another create was asked for- the parent foreign key default would still be in effect.

**Questions:

  1. Why am I getting the above error?
  2. How do I have the parent foreign key remain in effect between the list and the create pages upon repeated ‘create’ entries?
  3. Same question as 2- but returning repeatedly to create page with ‘back to list’ as way of navigating out?**

In general I am finding that creating of child records on a different razor page (standard scaffolding using entity framework) leaves a lot to be desired- quite cumbersome when the need to create child records prepopulating the parent foreign key would be a common scenario.

Thoughts?

Below are the cshtml files and cs files for the PositionSummary and PositionDetail

PositionSummary

@page
@model ThePositionerRazor2.Pages.PositionSummary.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<div class="row">
    <div class="col-md-12">
        <div class="panel panel-primary list-panel" id="list-panel">
            <div class="panel-heading list-panel-heading">
                <h1 class="panel-title list-panel-title">Position Summary</h1>
            </div>
            <div class="panel-body">
                <table id="Possum-data-table"
                       class="table table-striped table-bordered"
                       style="width:100%">
                    @*<table class="table">*@
                    <thead>
                        <tr>
                            <th>
                                @Html.DisplayNameFor(model => model.Possummary[0].PositionNbr)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.Possummary[0].WorkTitle)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.Possummary[0].Purpose)
                            </th>
                            
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var item in Model.Possummary)
                        {
                        <tr>
                            <td>
                                @Html.DisplayFor(modelItem => item.PositionNbr)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.WorkTitle)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Purpose)
                            </td>
                           
                        <td>
                            <a asp-page="./Edit" asp-route-id="@item.PositionId">Edit</a> |
                            @*<a asp-page="./Details" asp-route-id="@item.PositionId">Details</a> |*@
                            <a asp-page="../PositionDetail/Index" asp-route-id="@item.PositionId">Position Details</a> |

                            <a asp-page="./Delete" asp-route-id="@item.PositionId">Delete</a>
                        </td>
                        </tr>
                        }
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>
@section Scripts
    {
    <link href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap4.min.js "></script>

    <script type="text/javascript">
        $(document).ready(function () {

            $('#Possum-data-table').DataTable({ "order": [[0, "asc"]] });

        });
    </script>
}




using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using ThePositionerRazor2.Models;

namespace ThePositionerRazor2.Pages.PositionSummary
{
    public class IndexModel : PageModel
    {
        private readonly ThePositionerRazor2.Models.WorkManagerV4Context _context;

        public IndexModel(ThePositionerRazor2.Models.WorkManagerV4Context context)
        {
            _context = context;
        }

        public IList<Possummary> Possummary { get;set; }

        public async Task OnGetAsync()
        {
            Possummary = await _context.Possummary
                .Include(p => p.DescriptionType).ToListAsync();
        }
    }
}

Position Details Index

@page
@model ThePositionerRazor2.Pages.PositionDetail.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>



<p>
    <a asp-page="Create">Create New</a>
        <a asp-page="/PositionDetail/Create" asp-route-PositionID="@Model.Posdetail[0].PositionId">Create New</a>

</p>


<form method="post">
    <p>
        Desired Position: @Html.TextBox("SelectedPosition")
    </p>
    <input type="submit" value="Search Positions" />
    <div class="row">
        <div class="col-md-12">
            <div class="panel panel-primary list-panel" id="list-panel">
                <div class="panel-heading list-panel-heading">
                    <h1 class="panel-title list-panel-title">Position Detail</h1>
                </div>
                <div class="panel-body">
                    <table id="posdet-data-table"
                           class="table table-striped table-bordered"
                           style="width:100%">
                        @*<table class="table">*@
                        <thead>
                            <tr>
                                <th>
                                    @Html.DisplayNameFor(model => model.Posdetail[0].Position)
                                </th>
                                <th>

                                    @Html.DisplayNameFor(model => model.Posdetail[0].WorkitemNavigation)
                                </th>
                                <th>
                                    @Html.DisplayNameFor(model => model.Posdetail[0].TimeNrmz)
                                </th>
                                <th>
                                    @Html.DisplayNameFor(model => model.Posdetail[0].Importance)
                                </th>

                                <th>
                                    @Html.DisplayNameFor(model => model.Posdetail[0].Lastupdated)
                                </th>
                                <th></th>
                            </tr>
                        </thead>
                        <tbody>
                            @foreach (var item in Model.Posdetail)
                            {
                                <tr>
                                    <td>
                                        @Html.DisplayFor(modelItem => item.Position.PositionNbr)
                                    </td>
                                    <td>
                                        @Html.DisplayFor(modelItem => item.WorkitemNavigation.Workitemid)
                                    </td>
                                    <td>
                                        @Html.DisplayFor(modelItem => item.TimeNrmz)
  

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

the navigation back to the child list page results in an error

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')

To fix the error, you can try to pass selected PositionId through route value to Index page by modifying code like below.

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Posdetail.Add(Posdetail);
    await _context.SaveChangesAsync();

    var positionId = Posdetail.PositionId;

    return RedirectToPage("./Index", new { ID = positionId });
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...