MVC 5 ViewModel not working as it was in MVC 4 - c#

I will try to get straight to the point. I had some help building a ViewModel here on StackOverflow. It worked fine in MVC 4 but now that I am converting the application to MVC 5 it is not working. Nothing has changed in way of the code. I have a _navigation.cshtml which is a partial that is rendered in my Layout.cshtml and the error is within the For Loops in that Partial. This same code is working fine in MVC 4. Here is the code:
My error is in the partial page during the for loop and I get the error on Ingredient in the line:
#foreach (Ingredient ingredient in Model.Ingredients)
also in the same place on any other for loop in the same place. The error says:
The type or namespace name 'Recipe' could not be found (are you
missing a using directive or an assembly reference?)
Here is my code:
Models/Ingredient.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace XXX.Models
{
public class Ingredient
{
public int IngredientID { get; set; }
public string IngredientNameEs { get; set; }
}
}
Models/Recipe.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace XXX.Models
{
public class Recipe
{
public int RecipeID { get; set; }
public string RecipeNameEs { get; set; }
}
}
Models/IdentityModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Web;
using Microsoft.AspNet.Identity.EntityFramework;
using XXX.Models;
namespace XXX.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class,
// http://go.microsoft.com/fwlink/?LinkID=317594 for more.
public class ApplicationUser : IdentityUser
{
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(): base("DefaultConnection")
{
}
public DbSet<Ingredient> Ingredients { get; set; }
public DbSet<Recipe> Recipes { get; set; }
}
}
ViewModels/NavigationViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using XXX.Models;
namespace XXX.ViewModels
{
public class NavigationViewModel
{
public IEnumerable<Ingredient> Ingredients { get; set; }
public IEnumerable<Recipe> Recipes { get; set; }
}
}
Controllers/PartialsController.cs
using XXX.Models;
using XXX.ViewModels;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace XXX.Controllers
{
public class PartialController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
public ActionResult Navigation()
{
NavigationViewModel viewModel;
viewModel = new NavigationViewModel();
viewModel.Ingredients = db.Ingredients.Where(i => i.IsProduct != false).ToList();
viewModel.Recipes = db.Recipes.ToList();
return PartialView("_Navigation", viewModel);
}
}
}
Partials/_Navigation.cshtml (Asterisks indicate error near Ingredient and Recipe in For Loop)
#model XXX.ViewModels.NavigationViewModel
#using XXX.Models
//edited for brevity..
<li class="has-dropdown">#Html.ActionLink(XXX.Views.Shared.CultureSwap.Products, "Products", "Ingredient")
<ul class="dropdown">
#*//From NavigationViewModel print out each Product*#
#foreach (*Ingredient* ingredient in Model.Ingredients)
{
<li>#ingredient.IngredientNameEs</li>
}
</ul>
</li>
<li class="divider"></li>
<li class="has-dropdown">#Html.ActionLink(XXX.Views.Shared.CultureSwap.Recipes, "List", "Recipe")
<ul class="dropdown">
#foreach (*Recipe* recipe in Model.Recipes)
{
<li>#recipe.RecipeNameEs</li>
}
</ul>
</li>
Again the errors read:
The type or namespace name 'Ingredient' could not be found (are you
missing a using directive or an assembly reference?)
The type or namespace name 'Recipe' could not be found (are you
missing a using directive or an assembly reference?)
Here is a screenshot of the error in Visual Studio Next to the same code with no errors:

There is a web.config file located in the Views directory. In it the namespaces that should be available for the views are listed. Did you add a namespace to the views web.config in your mvc4 proj that you are now missing in the mvc5 proj?
The listing in the views web.config is a kind of global using statements that applies to all views.

Your view doesn't know where Ingredient or Recipe come from, you need to add a reference to the namespace which those types are under, add #using XXX.Models to the top of your view
#model XXX.ViewModels.NavigationViewModel
#using XXX.Models
...
#foreach (Ingredient ingredient in Model.Ingredients)
{
...
}
On a side-note you appear to have a half-baked view model implementation. In your NavigationViewModel you are referencing, which appear to be, domain models. It's generally recommended that anything exposed via a view model, is in actual fact, a view model itself. So in your case, I would introduce a couple of new view models to represent an Ingredient / Recipe i.e.
public class IngredientViewModel
{
...
}
public class RecipeViewModel
{
...
}
public class NavigationViewModel
{
public IEnumerable<IngredientViewModel> Ingredients { get; set; }
public IEnumerable<RecipeViewModel> Recipes { get; set; }
}
These would be be created under the XXX.ViewModels which would mean your view would look like
#using XXX.ViewModels
#model NavigationViewModel
...

Your view doesn't know where Ingredient or Recipe come from, you need to add a reference to the namespace which those types are under, add #using XXX.Models to the top of your view.

If your MVC application has Areas, check whether the namespace of the ViewModel and model reference in the Razor view is matched or not.
If the namespace of the view model contains Areas e.g. Areas.WebApp.Models , that view model won't be compiled in the view when you write #model WebApp.Models.
Both should match. So either remove Areas from ViewModel namespace or add the same fully qualified name in the View.

Related

MVC List<> error in model in reference to another model

There is an error in List<Story>:
the type or namespace name 'List<>' could not be found (are you
missing a using directive or an assembly reference?) (CS0246)
[project]
using System;
using project.Models;
namespace project.Models
{
public class Genre
{
public int GenreId { get; set; }
public string Name { get; set; }
public List<Story> Stories { get; set; }
}
}
You are missing a using statement using System.Collections.Generic;
Add a reference to System.Collections.Generic to the top of your class:
using System.Collections.Generic;
From your comment:
have another question: is it necessary to write namespace project.Models? and the reason
Namespaces are not mandatory but they help organise your code.
You don't need this line using project.Models; at the top of your class Genre. Genre is already in the namespace project.Models since you define that here:
// define the namespace for Genre
namespace project.Models
{
Since Genre is in the namespace project.Models you can reference any other class in Models without adding an explicit using.
However, when you reference Genre from a class which is in a different namespace (not in project.Models) you will need to add using project.Models to the top of that class. Otherwise, you could use the full reference Models.Genre.
This link has a good explanation of declaring, accessing and using namespaces.

The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies... and requires a model item of type

Got this error when I launch my 'Details' inside my Index on 'Firmas' (Generic auto-generated MS code):
Error
This is my model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using actiTest2.Context;
using System.Data.Entity;
namespace actiTest2.Models
{
public class PcontacFirmasModel
{
public Pcontac pcontac { get; set; }
public Firmas firmas { get; set; }
}
}
An the only call that I try to do atm:
#model actiTest2.Models.PcontacFirmasModel
#{
ViewBag.Title = Html.DisplayFor(model => model.firmas.NOMCOMP);
}
It seems that in the controller side, you are passing an object of type "Firmas" but your view is expecting the object "PcontacFirmasModel".
Update your action to send the PcontacFirmasModel object. you can use a mapper utility to map PcontacFirmasModel and Firmas.

MVC error when trying to use model in view

My problem occurs when I try to tell the view which model to use. It only happens with this model though.. Here is the model code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Com.Domain.Entities
{
public class Components
{
}
public class headerModel
{
public virtual String title { get; set; }
public virtual String subtitle { get; set; }
}
}
In the view when I try to add it like this
#model Com.Domain.Entities.headerModel;
It gives me this error:
only assignment call increment decrement and new object expressions can be used as a statement
I'm not sure what's going on. Any help would be appreciated! Thanks!
Remove ; at the end of the model declaration in your view
#model Com.Domain.Entities.headerModel

tree view Entity Model

I learn about making a tree view model etc , in this purpose I am making the following example
Model Tree.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace TreeTry1.Models
{
public class Tree
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int? Parent_Id { get; set; }
[ForeignKey("Parent_Id")]
public virtual ICollection<Tree> Group { get; set; }
}
}
Controller:
public ViewResult Show()
{
var roots = db.Tree.Where(r => r.Parent_Id == null);
return View(roots);
}
View
#model IEnumerable<TreeTry1.Models.Tree>
#{
Layout = null;
}
#foreach(var item in Model){
<li>
#item.Name
#if (item.Group.Count > 0)
{
<ul>
#{Html.RenderPartial("~/Views/Tree/TreeItem.cshtml", item.Group);}
</ul>
}
</li>
}
Partial View
#model IEnumerable<TreeTry1.Models.Tree>
<ul>
#Html.Partial("~/Views/Tree/TreeItem.cshtml")
</ul>
For now I recive error:
Error 1 The name 'db' does not exist in the current context
I thought that by making those classes (up) it will automatically create a database and entitiy models for that? If not then what should I do?
Do I need SQL Server for that? Or can I do it with MDF Database?
Thanks in advance for answers
YES you need a SqlServer database for that... EntityFramework is just an access layer to the underlying DB, it does not provide DB functionality by itself.
And regarding your "db not found" problem, the answer is quite obvious: where in your code did you define the variable db? no where. Visual Studio can generate the DatabaseContext class for you using database first, model first or code first. After that you'll initialize that instance in your controller like:
DatabaseContext db = new DatabaseContext();
Now the compiler knows what db is referring to!

what does this asp.net mvc compile time error states?

I have a repository class and it has this,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CrMVC.BusinessObjects;
namespace CrMVC.Models
{
public class ConstructionRepository
{
private CRDataContext db = new CRDataContext();
public IQueryable<MaterialsObj> FindAllMaterials()
{
var materials = from m in db.Materials
join Mt in db.MeasurementTypes on m.MeasurementTypeId equals Mt.Id
select new MaterialsObj()
{
Id = Convert.ToInt64(m.Mat_id),
Mat_Name = m.Mat_Name,
Mes_Name = Mt.Name,
};
return materials;
}
}
}
And My MaterialsObj class is under CrMVC.BusinessObjects namespace and i using it in my repository class....
namespace CrMVC.BusinessObjects
{
public class MaterialsObj
{
//My logic here
}
}
But when i compile this i get this error
c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET
Files\root\19360d4c\3d21e226\App_Web_materials.aspx.7d2669f4.a8f-zsw5.0.cs(148):
error CS0426: The type name 'Materials' does not exist
in the type 'CrMVC.Models.ConstructionRepository'
Am i missing something any suggestion....
Edit:
There is no class named Materials in my repository class then why i get this error..
My view page has this,
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<CrMVC.Models.ConstructionRepository+Materials>>" %>
You are referencing the type CrMVC.Models.ConstructionRepository.Materials in your ASPX when you probably want to reference CrMVC.BusinessObjects.MaterialsObj instead.

Categories