Dropdown blank when rendered as partial

MaxPowers1982 81 Reputation points
2021-07-01T20:44:23.467+00:00

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
111068-image.png

Please note: The /Childs/Create (not a partial view) AnotherTableId does display contents
110969-image.png

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">&times;</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);  
    }  
}  
Entity Framework Core
Entity Framework Core
A lightweight, extensible, open-source, and cross-platform version of the Entity Framework data access technology.
697 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,157 questions
0 comments No comments
{count} votes

Accepted answer
  1. Rena Ni - MSFT 2,061 Reputation points
    2021-07-02T06:12:38.827+00:00

    Hi @MaxPowers1982 ,

    Child actions follow a different controller/model/view lifecycle than parent actions, so they do not share ViewData/ViewBag.

    Here is a workaround you could follow:

    _Child.cshtml:

    @model  CreateModel  
    <select asp-for="Child.AnotherTableId" class="form-control" asp-items="Model.AnotherTableSelectList"></select>      
    

    Create.cshtml.cs:

    public class CreateModel : PageModel  
    {  
        private readonly TelerikTest.Models.Scaffold.TelerikTestDBContext _context;  
      
        public CreateModel(TelerikTest.Models.Scaffold.TelerikTestDBContext context)  
        {  
            _context = context;  
        }  
         
        //...  
      
        [BindProperty]  
        public Child Child { get; set; }  
    
        public SelectList AnotherTableSelectList { get; set; }  //add this...  
      
        public PartialViewResult OnGetChildPartial()  
        {  
            AnotherTableSelectList = new SelectList(_context.AnotherTables, "AnotherTableId", "AnotherTableName");  
            //add the following code...  
            var data = new CreateModel(_context);  
            data.AnotherTableSelectList = AnotherTableSelectList;  
            return Partial("/Pages/Shared/_Child.cshtml", data);  
        }  
    }  
    

    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best Regards,

    Rena


0 additional answers

Sort by: Most helpful