Tshumore Ответов: 1

Как привязать выпадающий список в EF 6 с помощью database-first


Когда я пытаюсь загрузить страницу с моим выпадающим списком я получаю ошибку "
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'
. В модели автоматически (сервером.кс) я вручную добавлен SelectListItem как показано ниже :
<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; }
}


Это моя структура таблиц по умолчанию в SqlServer :
Таблица серверов
инт если мы приобретем
nvarchar(50) ServerIp
int ApplicationId

а выпадающий список привязывается к таблице ниже :
Приложение
int ApplicationId
nvarchar(50) ApplicationName.

и создается модель :
public partial class Application
       {
       public int ApplicationId { get; set; }
       public string ApplicationName { get; set; }
       }


В репозитории(ServersService.cs) я извлекаю данные, как показано ниже :
<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");
            }
        }


А потом в контроллере я подключил как :
// 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);
       }


Что я уже пробовал:

На данный момент из моих исследований следует, что нет прямого способа добавить такие свойства, как SelectListItem, в автогенерированную модель в базе данных в первую очередь. Любая помощь в том, как я могу достичь этого, используя первый подход к базе данных или, по крайней мере, рефакторинг того, как я реализовал свой код. Единственное, что я видел до сих пор, что можно добавить к этому частичному классу, - это аннотации данных.

1 Ответов

Рейтинг:
9

Richard Deeming

Цитата:
var apps = serversService.GetApplications();
return View(apps);
Переменная apps это IEnumerable<SelectListItem>.

Согласно сообщению об ошибке, представление ожидает, что модель будет FBChecklist.Server пример.

Либо измените @model директива на вашем представлении, чтобы соответствовать модели, которую вы передаете ему, или измените действие, чтобы передать правильный тип модели в представление.

Если вы хотите добавить свойства, существующие только для представления, то используйте модель представления.
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;
    }
}
Действие:
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");
}
Смотреть:
@model ServerViewModel
...


Tshumore

Прекрасно ! Работает как заклинание