Reputation: 835
I am trying to use 2 models in 1 view in an ASP.NET MVC application and am trying to use the dynamic model approach as described here: https://www.c-sharpcorner.com/UploadFile/ff2f08/multiple-models-in-single-view-in-mvc/
This is my controller:
// GET: Statewides/Details/5
public ActionResult Details(int? id)
{
ViewBag.ID = id;
var today = DateTime.Today;
var todayAsString = today.ToString("MM/dd/yyyy");
ViewBag.Today = todayAsString;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Statewide statewide = db.Statewides.Find(id);
var document = from s in db.Documents
where s.Statewide_ID == id
select s;
dynamic mymodel = new ExpandoObject();
mymodel.Statewides = statewide;
mymodel.Documents = document;
if (statewide == null)
{
return HttpNotFound();
}
return View(mymodel);
}
And this is a part of my view:
@model dynamic
@{
ViewBag.Title = "Details";
}
<div class="row">
<div class="col-md-9 text-left">
<h5><strong>COUNTY:</strong> <span class="box-shadow px-3">@Model.Statewide.COUNTY</span></h5>
</div>
<div class="col-md-3 text-right district">
<h5><strong>District:</strong>@Model.Statewide.District</h5>
</div>
</div>
And at the bottom of that page I need to access the Documents model:
<table>
<tr>
<th>Doc Type</th>
<th>Order Date</th>
<th>Location</th>
</tr>
@foreach (Document document in Model.Documents)
{
<tr>
<td>@document.Doc_Type</td>
<td>@document.Order_Date</td>
<td>@document.Doc_Location</td>
</tr>
}
</table>
Here I get an error on Document
saying "The type or namespace Document could not be found". I'm not exactly sure what I'm doing wrong as it looks to me like I've done the same thing as the guide.
Here is the full view if you need it, PLEASE NOTE I have not changed a lot of the instances of the retrieving values from the old model that was only Statewide. Please ignore those:
@model dynamic
<!-- CUSTOM CSS -->
<link href="~/Styles/Documents/DetailsStyle.css" type="text/css" rel="stylesheet">
<!-- GOOGLE ICONS -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
@{
ViewBag.Title = "Details";
}
<div class="bigContainer">
<div class="container-fluid text-center topLabel">
<div class="borderline">
<h4 class="title"><strong>DETAIL RECORD - RP ROADWAY HISTORY FILE</strong></h4>
<div class="row">
<div class="col-md-1 printButton">
<input class="text-left" type="button" onclick="javascript:window.print()" value="Print" runat="server" />
</div>
<div class="col-md-11">
<p class="text-right">
<u>Current Date:</u>
<script>document.write(new Date().toLocaleDateString());</script>
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-9 text-left">
<h5><strong>COUNTY:</strong> <span class="box-shadow px-3">@Model.Statewide.COUNTY</span></h5>
</div>
<div class="col-md-3 text-right district">
<h5><strong>District:</strong>@Model.Statewide.District</h5>
</div>
</div>
<div class="row">
<div class="col-md-4 text-left">
<h5><strong>Route No:</strong><span class="box-shadow px-4">@Html.DisplayFor(model => model.RouteNo)</span></h5>
</div>
<div class="col-md-4">
<h5><strong>Sign System:</strong><span class="box-shadow px-4 sign">@Html.DisplayFor(model => model.SignSys)</span></h5>
</div>
<div class="col-md-4"></div>
</div>
<div class="row">
<div class="col-md-12 text-left">
<h5><strong>LocalName:</strong></h5>
</div>
</div>
<div class="row">
<div class="col-md-4 text-left">
<h5 class="box-shadow px-3 localName">@Html.DisplayFor(model => model.LocalName)</h5>
</div>
<div class="col-md-8"></div>
</div>
<div class="row suppMethodDuplicate">
<div class="col-md-2 text-right">
<h5><strong>Supp Des:</strong></h5>
</div>
<div class="col-md-2 text-left">
<h5>@Html.DisplayFor(model => model.SuppDes)</h5>
</div>
<div class="col-md-2 text-right">
<h5><strong>Method:</strong></h5>
</div>
<div class="col-md-2 text-left">
<h5>@Html.DisplayFor(model => model.Method)</h5>
</div>
<div class="col-md-1"></div>
<div class="col-md-2 text-left">
@Html.DisplayFor(model => model.Duplicate_OK)
<label class="form-check-label" for="duplicateCheck"><strong>Duplicate OK</strong></label>
</div>
</div>
<div class="row">
<div class="col-md-2 text-right">
<h5><strong>Date:</strong></h5>
</div>
<div class="col-md-2 text-left">
<h5>@Html.DisplayFor(model => model.ReservedDate)</h5>
</div>
<div class="col-md-2 text-right">
<h5><strong>Original Location:</strong></h5>
</div>
<div class="col-md-2 text-left">
<h5>@Html.DisplayFor(model => model.OriginalL)</h5>
</div>
</div>
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-2 text-right">
<h5><strong>Original D:</strong></h5>
</div>
<div class="col-md-6 text-left">
<h6>@Html.DisplayFor(model => model.OriginalD)</h6>
</div>
</div>
<div class="borderline text-left">
<h5 class="mb-0"><strong>DOCUMENTS</strong></h5>
</div>
<table>
<tr>
<th>Doc Type</th>
<th>Order Date</th>
<th>Location</th>
</tr>
@foreach (Document document in Model.Documents)
{
<tr>
<td>@document.Doc_Type</td>
<td>@document.Order_Date</td>
<td>@document.Doc_Location</td>
</tr>
}
</table>
<div class="borderline text-left">
<h5 class="mb-0"><strong>PROJECTS</strong></h5>
</div>
<h6 class="text-left">@Html.DisplayFor(model => model.Projects)</h6>
<div class="borderline text-left">
<h5 class="mb-0"><strong>COMMENTS</strong></h5>
</div>
<h6 class="text-left">@Html.DisplayFor(model => model.Comments)</h6>
</div>
<p style="margin-top: 20px">
@Html.ActionLink("Back to List", "Index")
</p>
</div>
Serge suggested I use view model so I have tried this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Roadway_History.Models
{
public class ViewModel
{
public Statewide Statwide { get; set; }
public Document Document { get; set; }
}
}
// GET: Statewides/Details/5
public ActionResult Details(int? id)
{
ViewBag.ID = id;
var today = DateTime.Today;
var todayAsString = today.ToString("MM/dd/yyyy");
ViewBag.Today = todayAsString;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var model = new ViewModel
{
Statewide statewide = db.Statewides.Find(id);
var document = from s in db.Documents
where s.Statewide_ID == id
select s;
};
if (statewide == null)
{
return HttpNotFound();
}
return View(model);
}
But this also doesn't work. I get the errors
Statewide is a type which is not valid in the given context
and ViewModel does not contain a definition for statewide
I belive the action method to be wrong but I'm not sure how to fix it.
Also, using @model ViewModel
in the view gives the error "The type or namespace ViewModel could not be found"
Upvotes: 0
Views: 633
Reputation: 43969
if you need to use two models for one view you can make a viewmodel that contains both of them
public class ViewModel
{
public Statewide Statwide {get; set;}
public List<Document> Documents {get; set;}
}
in the view
@model ViewModel
action
var model = new ViewModel
{
Statewide= ... your code
Document=... your code
};
......
return View(model);
UPDATE
fix your viewmodel like this
var statewide = db.Statewides.FirstOrDefault (i=> i.Id==id);
if (statewide == null)
{
return HttpNotFound();
}
var documents = db.Documents.Where(s=> s.Statewide_ID == id).ToList();
if (documents == null)
{
return HttpNotFound();
}
var model = new ViewModel
{
Statewide =statewide,
Documents = documents
};
return View(model);
but you will need to fix model too according to new viewmodel
Upvotes: 1