Search code examples
asp.net-core-mvcmultiple-views

Using multiple ASP.NET Core MVC models in a view


In my ASP.NET Core MVC app, I have a registration page, it uses a model class. I am using Dapper for database connectivity. The form works well, no issues. I need to add another model so that I can display some more information about the product in the sidebar.

@model Core.Library.Models.Lead; 
...............

<div class="col-md-6">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="FirstName" class="control-label">First Name</label>
        <input asp-for="FirstName" class="form-control" />
        <span asp-validation-for="FirstName" class="text-danger"></span>
    </div>
</div>

Approach #1

In the controller, I am passing the result in the view like below.

var Result = _db.Query<BoatBasic>(

Boats.GetBasicSummaryWithEngine(BoatId, SourceWebsite)).ToList();

return View(Result);

But when I try to iterate, I get an error:

@foreach (var item in Model)
{
    // ...
}

Error CS1579
foreach statement cannot operate on variables of type 'Lead' because 'Lead' does not contain a public instance or extension definition for 'GetEnumerator'

Approach #2

Then I tried to pass through through ViewBag:

ViewBag.BoatBasic = _db.Query<BoatBasic>(

Boats.GetBasicSummaryWithEngine(BoatId, SourceWebsite)).ToList();

And I am using lambda expression to iterate over it:

@BoatBasic.ForEach(x =>
{
     var tmpMonthNameYear = x.MonthNameYear;
});

Error CS1977
Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.

Approach #3

I have tried composite model as suggested in different question. But that also didn't work.

string BoatId = ViewBag.BoatId;
CompositeModel compositeModel = new CompositeModel
{
    lead = new Core.Library.Models.Lead(),
    boatBasic = _db.Query<BoatBasic>(Boats.GetBasicSummaryWithEngine(BoatId, SourceWebsite)).ToList()
};
return View(compositeModel);
    
public class CompositeModel
{
    public Lead lead;
    public List<BoatBasic> boatBasic;
}

In the view:

@foreach (var item in Model.boatBasic)
{
    // ...
    <h5 class="text-muted">Model:</h5>
    <p style="margin-left: 10px;">@item.Model</p>
    // ...
}

Error CS1061
'Lead' does not contain a definition for 'boatBasic' and no accessible extension method 'boatBasic' accepting a first argument of type 'Lead' could be found (are you missing a using directive or an assembly reference?)

I am stuck on how to proceed. I have explored many solutions on this website, but somehow I'm not able to crack it. Please advise.


Solution

  • Approach #3 would be the way to go - but you need to do two things:

    #1: you need to use properties (not class fields) for your values in CompositeModel:

    public class CompositeModel
    {
        public Lead lead { get; set; }
        public List<BoatBasic> boatBasic { get; set; }
    }
    

    #2: you need to change the view's @model directive to reference that CompositeModel:

    @model Core.Library.Models.CompositeModel;