Click here to Skip to main content
15,886,362 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
When i try to load the page with my DropDownList i get an error "
The model item passed into the dictionary is of type 'System.Web.Mvc.SelectList', but this dictionary requires a model item of type 'FBChecklist.Server'
. In the autogenerated model (Server.cs) i manually added the SelectListItem as below :
C#
<pre>public partial class Application
    {       
public int ServerId { get; set; }
  public string ServerIp { get; set; }
  public Nullable<int> ApplicationId { get; set; }
  public IEnumerable<SelectListItem> Applications { get; set; }
}


This is my default table structure in SqlServer :
Server table
int ServerId
nvarchar(50) ServerIp
int ApplicationId

and the DropDownList binds from the table below :
Application
int ApplicationId
nvarchar(50) ApplicationName.

and the generated model :
C#
public partial class Application
       {
       public int ApplicationId { get; set; }
       public string ApplicationName { get; set; }
       }


In the repository(ServersService.cs) i'm retrieving the data as below :
C#
<pre> public IEnumerable<SelectListItem> GetApplications()
        {
            using (var db = new AppEntities())
            {
                List<SelectListItem> applications = db.Applications.AsNoTracking()
                    .OrderBy(n => n.ApplicationName)
                        .Select(n =>
                        new SelectListItem
                        {
                            Value = n.ApplicationId.ToString(),
                            Text = n.ApplicationName
                        }).ToList();
                var apptip = new SelectListItem()
                {
                    Value = null,
                    Text = "--- select application ---"
                };
                applications.Insert(0, apptip);
                return new SelectList(applications, "Value", "Text");
            }
        }


And then in the Controller i have wired up as :
C#
// GET: Servers/Create
       public ActionResult Create()
       {
           var apps = serversService.GetApplications();
           return View(apps);
       }


       [HttpPost]
       [ValidateAntiForgeryToken]
       public ActionResult Create([Bind(Include = "ServerIp,ServerName,CreatedBy,CreatedOn")] Server server)
       {
           if (ModelState.IsValid)
           {
               serversService.AddServer(server); ;

               return RedirectToAction("Index");
           }

           return View(server);
       }


What I have tried:

For now it appears from my research there is no direct way to add properties such as SelectListItem to the autogenerated model in Database First. Any assistance on how i can achieve this using Database First approach or at least refactor the way i have implemented my code. The only thing i have seen yet that can be added to this partial class is Data Annotations.
Posted
Updated 19-May-20 2:08am

1 solution

Quote:
C#
var apps = serversService.GetApplications();
return View(apps);
The variable apps is an IEnumerable<SelectListItem>.

According to the error message, the view expects the model to be a FBChecklist.Server instance.

Either change the @model directive on your view to match the model you're passing to it, or change the action to pass the correct model type to the view.

If you want to add properties that only exist for the view, then use a view-model.
C#
public class ServerViewModel
{
    public ServerViewModel(Server server)
    {
        ServerId = server.ServerId;
        ServerIp = server.ServerIp;
        ApplicationId = server.ApplicationId;
    }
    
    public ServerViewModel()
    {
    }
    
    public int ServerId { get; set; }
    public string ServerIp { get; set; }
    public int? ApplicationId { get; set; }
    public IEnumerable<SelectListItem> Applications { get; internal set; }
    
    public void UpdateModel(Server server)
    {
        server.ServerIp = ServerIp;
        server.ApplicationId = ApplicationId;
    }
}
Action:
C#
private void PopulateLookups(ServerViewModel model)
{
    model.Applications = serversService.GetApplications();
}

[HttpGet]
public ActionResult Create()
{
    var model = new ServerViewModel();
    PopulateLookups(model);
    return View(model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ServerViewModel model)
{
    if (!ModelState.IsValid)
    {
        PopulateLookups(model);
        return View(model);
    }
    
    var server = new Server();
    model.UpdateModel(server);
    serversService.AddServer(server);

    return RedirectToAction("Index");
}

[HttpGet]
public ActionResult Edit(int serverId)
{
    var server = serversService.GetServerById(serverId);
    if (server == null) return RedirectToAction("Index");
    
    var model = new ServerViewModel(server);
    PopulateLookups(model);
    return View(model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ServerViewModel model)
{
    var server = serversService.GetById(model.ServerId);
    if (server == null) return RedirectToAction("Index");
    
    if (!ModelState.IsValid)
    {
        PopulateLookups(model);
        return View(model);
    }
    
    model.UpdateModel(server);
    serversService.UpdateServer(server);

    return RedirectToAction("Index");
}
View:
Razor
@model ServerViewModel
...
 
Share this answer
 
Comments
Tshumore 22-May-20 2:40am    
Perfect ! Works like a charm

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900