I am attempting to perform CRUD operations on table Child via a modal dialogue that loads a partial view that is triggered from the Parent Details page. In this example I am starting with the create operation.
Problem 1: The dropdown for AnotherTaleId in the partial has no contents
Please note: The /Childs/Create (not a partial view) AnotherTableId does display contents
Pages > Parent > Details.cshtml
@page
@model TelerikTest.Pages.Parents.DetailsModel
@{
ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
<h4>Parent</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Parent.ParentName)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Parent.ParentName)
</dd>
</dl>
</div>
<div>
<a asp-page="./Edit" asp-route-id="@Model.Parent.ParentId">Edit</a> |
<a asp-page="./Index">Back to List</a>
</div>
<div>
<button class="btn btn-sm btn-dark details" data-id="@Model.Parent.ParentId" data-toggle="modal" data-target="#details-modal">Details</button>
</div>
<div class="modal fade" tabindex="-1" role="dialog" id="details-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Create Child</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body"></div>
</div>
</div>
</div>
@section scripts{
<script>
$(function () {
$('button.details').on('click', function () {
$('.modal-body').load('/Childs/create?handler=ChildPartial');
});
})
</script>
}
Pages > Shared > _Child (the partial)
@model TelerikTest.Pages.Childs.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Child</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Child.ParentId" class="control-label"></label>
<input asp-for="Child.ParentId" class="form-control" >
</div>
<div class="form-group">
<label asp-for="Child.ChildName" class="control-label"></label>
<input asp-for="Child.ChildName" class="form-control" />
<span asp-validation-for="Child.ChildName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Child.AnotherTableId" class="control-label"></label>
<select asp-for="Child.AnotherTableId" class="form-control" asp-items="ViewBag.AnotherTableId"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
Pages > Childs > Create.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using TelerikTest.Models.Scaffold;
namespace TelerikTest.Pages.Childs
{
public class CreateModel : PageModel
{
private readonly TelerikTest.Models.Scaffold.TelerikTestDBContext _context;
public CreateModel(TelerikTest.Models.Scaffold.TelerikTestDBContext context)
{
_context = context;
}
public IActionResult OnGet()
{
ViewData["AnotherTableId"] = new SelectList(_context.AnotherTables, "AnotherTableId", "AnotherTableName");
ViewData["ParentId"] = new SelectList(_context.Parents, "ParentId", "ParentName");
return Page();
}
[BindProperty]
public Child Child { get; set; }
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Children.Add(Child);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
public PartialViewResult OnGetChildPartial()
{
ViewData["AnotherTableId"] = new SelectList(_context.AnotherTables, "AnotherTableId", "AnotherTableName");
return Partial("/Pages/Shared/_Child.cshtml");
}
}
}
Pages > Childs > Create.cshtml (the dropdowns display contents on this)
@page
@model TelerikTest.Pages.Childs.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Child</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Child.ParentId" class="control-label"></label>
<select asp-for="Child.ParentId" class ="form-control" asp-items="ViewBag.ParentId"></select>
</div>
<div class="form-group">
<label asp-for="Child.ChildName" class="control-label"></label>
<input asp-for="Child.ChildName" class="form-control" />
<span asp-validation-for="Child.ChildName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Child.AnotherTableId" class="control-label"></label>
<select asp-for="Child.AnotherTableId" class ="form-control" asp-items="ViewBag.AnotherTableId"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
TelerikTestDBContext.cs
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
#nullable disable
namespace TelerikTest.Models.Scaffold
{
public partial class TelerikTestDBContext : DbContext
{
public TelerikTestDBContext()
{
}
public TelerikTestDBContext(DbContextOptions<TelerikTestDBContext> options)
: base(options)
{
}
public virtual DbSet<AnotherTable> AnotherTables { get; set; }
public virtual DbSet<Child> Children { get; set; }
public virtual DbSet<OneTable> OneTables { get; set; }
public virtual DbSet<Parent> Parents { get; set; }
public virtual DbSet<Dashboard> Dashboards { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
optionsBuilder.UseSqlServer("Data Source=(localdb)\\ProjectsV13;Integrated Security=True;Connect Timeout=60;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;Initial Catalog=TelerikTestDB");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");
modelBuilder.Entity<AnotherTable>(entity =>
{
entity.ToTable("AnotherTable");
entity.Property(e => e.AnotherTableName)
.IsRequired()
.HasMaxLength(50);
});
modelBuilder.Entity<Child>(entity =>
{
entity.ToTable("Child");
entity.Property(e => e.ChildName)
.IsRequired()
.HasMaxLength(50);
entity.HasOne(d => d.AnotherTable)
.WithMany(p => p.Children)
.HasForeignKey(d => d.AnotherTableId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Child_AnotherTable");
entity.HasOne(d => d.Parent)
.WithMany(p => p.Children)
.HasForeignKey(d => d.ParentId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Child_Parent");
});
modelBuilder.Entity<OneTable>(entity =>
{
entity.ToTable("OneTable");
entity.Property(e => e.Afield).HasMaxLength(50);
});
modelBuilder.Entity<Parent>(entity =>
{
entity.ToTable("Parent");
entity.Property(e => e.ParentName)
.IsRequired()
.HasMaxLength(50);
});
modelBuilder.Entity<Dashboard>(entity =>
{
entity.HasKey(c => new { c.ParentId });
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}