GrillOwner69420
GrillOwner69420

Reputation: 835

ASP.NET MVC Dynamic Model not being recognized

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:

Details 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:

ViewModel

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; }
    }
}

Action

// 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 contextand 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

Answers (1)

Serge
Serge

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

Related Questions