.Net 6 MVC - ViewModel - Displaying Second Property in a View

86 views Asked by At

Premise:

I'm trying to use a very simplified .net 6 MVC project to gain understanding of how to code ViewModels.

Thumbnail of Project

Models A B C (Joining Class)

ViewModel AB


**GitHub **

Environment: Net Core 6 MVC, Visual Studio Community 2022 (64 bit), WIndows 11

Please: whenever possible, provide help in the form of actual code - preferably changes to the code I've provided (a fair amount of time and effort goes into providing this code as the premise for the question) - or in example(s) of code you provide, in either case, in the format / syntax the code needs to be in to make the project. Abstraction, more often than not, obfuscates the answer.


Question

Why does data from the first property display but not from the second property? How do I change the controller action method code (below) to also display data from the second property?

Controller

ViewModel

Controller Action Method displays successfully as pictured (above)

        //GET: AB
        public IActionResult AB2()
        {
            //define a variable to store the return data.
            var ab2 = new List<AB>();
            //query A and B table, 
            var Alist = _context.A.ToList();
            var Blist = _context.B.ToList();
            //use foreach statement to filter data. And Add A and B to the ab list.
            foreach (var item in Alist)
            {
                var newab = new AB()
                {
                    A = item
                };
                //add the new item into the list.
                ab2.Add(newab);
            }
            return View(ab2); // return the list to the view page.
        }

**Full Code **

Models

A

    namespace ViewModel.Models
    {
    public class A
        {
        public int Id { get; set; }

        public string? One { get; set; }

        public string? Two { get; set; }

        public string? Three { get; set; }

        public IEnumerable<C>? C { get; set; }

        }
   }

B

namespace ViewModel.Models
{
    public class B
    {
        public int Id { get; set; }

        public string? One { get; set; }

        public string? Two { get; set; }

        public string? Three { get; set; }

        public IEnumerable<C>? C { get; set; }
    }
}

C

using System.Security.Cryptography.Xml;

namespace ViewModel.Models
{
    public class C
    {
        public int Id { get; set; }

        public int AId { get; set; }

        public int BId { get; set; }

        // _______________________________________

        public A? A { get; set; }
        public B? B { get; set; }
    }
}

Context

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ViewModel.Models;

namespace ViewModel.Data
{
    public class ViewModelContext : DbContext
    {
        public ViewModelContext (DbContextOptions<ViewModelContext> options)
            : base(options)
        {
        }

        public DbSet<ViewModel.Models.A> A { get; set; } = default!;

        public DbSet<ViewModel.Models.B>? B { get; set; }

        public DbSet<ViewModel.Models.C>? C { get; set; }
    }
}

ViewModel

using System.Security.Cryptography.Xml;

namespace ViewModel.Models.View
{
    public class AB
    {
        public A? A { get; set; }

        public B? B { get; set; }
    }
}

View

@model IEnumerable<ViewModel.Models.View.AB>

@{
    ViewData["AB2"] = "AB2";
}

<h1>AB2</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                Property Set A, Property @Html.DisplayNameFor(model => model.A.One)
            </th>
            <th>
                Property Set B, Property @Html.DisplayNameFor(model => model.B.One)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.A.One)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.B.One)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.A.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.A.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.A.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

I created simplified project to use as a premise for this question. I have a working view derived through a viewmodel that includes a property from each of two classes. My question is now about a second view, coded in the controller differently from the first that displays a property from one class. I'm trying to get a second property from a second class to display.


I've tried a few changes to the controller action method code. Both failed:

        //GET: AB
    public IActionResult AB2()
    {
        //define a variable to store the return data.
        var ab2 = new List<AB>();
        //query A and B table, 
        var Alist = _context.A.ToList();
        var Blist = _context.B.ToList();
        //use foreach statement to filter data. And Add A and B to the ab list.
        foreach (var item in Alist)
        {
            var newab = new AB()
            {
                A = item
              //B = item                  **2nd change: did not work**
            };
            //add the new item into the list.
            ab2.Add(newab);
        }

        //foreach (var item in Blist)    **1st change: did not work**
        //{
        //    var newab = new AB()
        //    {
        //        B = item
        //    };
        //    //add the new item into the list.
        //    ab2.Add(newab);
        //}

        return View(ab2); // return the list to the view page.
    }
0

There are 0 answers