question

MaxPowers1982-8385 avatar image
0 Votes"
MaxPowers1982-8385 asked tinywang-msft edited

Edit PartialView - How to load model

I would like to be able to perform edits using a partial view that is loaded via a modal. There are at least two problems with this attempt.

1) Upon attempting to load the modal, I get this error
117148-image.png

2) If I remove the offending line 28, the modal loads but ParentId and ChildName are blank, I would expect them to be populated from the id being passed into the partial view.

How can this be done properly?

Pages > Childs > Edit.cshtml.cs

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 using Microsoft.AspNetCore.Mvc.Rendering;
 using Microsoft.EntityFrameworkCore;
 using TelerikTest.Models.Scaffold;
    
 namespace TelerikTest.Pages.Childs
 {
     public class EditModel : PageModel
     {
         private readonly TelerikTest.Models.Scaffold.TelerikTestDBContext _context;
    
         public EditModel(TelerikTest.Models.Scaffold.TelerikTestDBContext context)
         {
             _context = context;
         }
    
         [BindProperty]
         public Child Child { get; set; }
         public SelectList AnotherTableSelectList { get; set; }  //add this...
    
    
         public async Task<IActionResult> OnGetAsync(int? id)
         {
             if (id == null)
             {
                 return NotFound();
             }
    
             Child = await _context.Children
                 .Include(c => c.AnotherTable)
                 .Include(c => c.Parent).FirstOrDefaultAsync(m => m.ChildId == id);
    
             if (Child == null)
             {
                 return NotFound();
             }
            ViewData["AnotherTableId"] = new SelectList(_context.AnotherTables, "AnotherTableId", "AnotherTableName");
            ViewData["ParentId"] = new SelectList(_context.Parents, "ParentId", "ParentName");
             return Page();
         }
    
         public PartialViewResult OnGetChildPartial(int id)
         {
    
             /*
                         Child = _context.Children
                             .Include(c => c.AnotherTable)
                             .Include(c => c.Parent).FirstOrDefault(m => m.ChildId == id);
    
                        ViewData["AnotherTableId"] = new SelectList(_context.AnotherTables, "AnotherTableId", "AnotherTableName");
                        ViewData["ParentId"] = new SelectList(_context.Parents, "ParentId", "ParentName");
             */
    
             AnotherTableSelectList = new SelectList(_context.AnotherTables, "AnotherTableId", "AnotherTableName");
             var data = new EditModel(_context);
    
             //data.Child = new Child { ChildId = id };
             data.Child = _context.Children
                             .Include(c => c.AnotherTable)
                             .Include(c => c.Parent).FirstOrDefault(m => m.ChildId == id);
                
             data.AnotherTableSelectList = AnotherTableSelectList;
    
             return Partial("/Pages/Shared/_ChildEdit.cshtml", Child);
         }
    
         // To protect from overposting attacks, enable the specific properties you want to bind to.
         // For more details, see https://aka.ms/RazorPagesCRUD.
         public async Task<IActionResult> OnPostAsync()
         {
             if (!ModelState.IsValid)
             {
                 return Page();
             }
    
             _context.Attach(Child).State = EntityState.Modified;
    
             try
             {
                 await _context.SaveChangesAsync();
             }
             catch (DbUpdateConcurrencyException)
             {
                 if (!ChildExists(Child.ChildId))
                 {
                     return NotFound();
                 }
                 else
                 {
                     throw;
                 }
             }
    
             return RedirectToPage("./Index");
         }
    
         private bool ChildExists(int id)
         {
             return _context.Children.Any(e => e.ChildId == id);
         }
     }
 }

Pages > Shared > _ChildEdit.cshtml

 @model TelerikTest.Pages.Childs.EditModel
    
 @{
     ViewData["Title"] = "Edit";
 }
    
 <h1>Create</h1>
    
 <h4>Child</h4>
 <hr />
 <div class="row">
     <div class="col-md-4">
         <form method="post" asp-page-handler="ChildPartial">
             <input name="IsValid" type="hidden" value="@ViewData.ModelState.IsValid.ToString()" />
             <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="Model.AnotherTableSelectList"></select>
             </div>
             <div class="form-group">
                 <!--<input type="submit" value="Create" class="btn btn-primary" />-->
             </div>
         </form>
     </div>
 </div>

Models > Child.cs

 using System;
 using System.Collections.Generic;
    
 #nullable disable
    
 namespace TelerikTest.Models.Scaffold
 {
     public partial class Child
     {
         public int ChildId { get; set; }
         public int ParentId { get; set; }
         public string ChildName { get; set; }
         public int AnotherTableId { get; set; }
    
         public virtual AnotherTable AnotherTable { get; set; }
         public virtual Parent Parent { get; set; }
     }
 }

Models > Scaffold > 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 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);
     }
 }


dotnet-entity-framework-coredotnet-aspnet-core-razor
image.png (121.1 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

tinywang-msft avatar image
0 Votes"
tinywang-msft answered tinywang-msft edited

Hi @MaxPowers1982-8385 , I tried to reproduce you issue in my side and I found that it may comes from initializing of AnotherTableSelectList, I'll show my details below:

Test2.cshtml contains in Shared folder and error appears when my EditModel hasn't set value for menus
117451-image.png


Edit.cshtml

 @page
 @model WebApplication1.Pages.Childs.EditModel
 @{
     ViewData["Title"] = "Edit";
 }
 <partial name="~/Pages/Shared/Test2.cshtml" />


Edit.cshtml.cs

 using System.Collections.Generic;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 using WebApplication1.Models;
    
 namespace WebApplication1.Pages.Childs
 {
     public class EditModel : PageModel
     {
         public List<Menu> menus { get; set; }
    
         public IActionResult OnGet(int? id) {
             return Page();
         }
    
     }
 }


But if I set default value like this :

 public List<Menu> menus { get; set; } = new List<Menu>
         {
             new Menu{ MenuName="m1", MenuId=1 }
         };

It worked well. And certainly, it's ok to set value in onGet method like:

 public class EditModel : PageModel
     {
         public List<Menu> menus { get; set; }
    
         public IActionResult OnGet(int? id) {
             menus = new List<Menu>
             {
                 new Menu{ MenuName="m2", MenuId=1 }
             };
             return Page();
         }
    
     }


I think you can try my idea in your code, or provide code snippet of Edit.cshtml? I don't know how you call method OnGetChildPartial, at least in my side, I didn't find this method be called as I set debug point in it. Or you may move the method into OnGet ?


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,
TinyWang







image.png (33.2 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.