将MVC DropDownlistFor()绑定到模型的Navigation属性

时间:2013-01-28 01:03:10

标签: c# .net asp.net-mvc asp.net-mvc-4

我正在为我的C#MVC课程编写一个简单的教程应用程序,我们的教授让我们使用会话和列表在内存系统中使用了一些可怕的神,因为他还没有开始教授实体框架

我遇到的问题是,当我尝试将下拉列表绑定到我的模型时,它会给我一个意想不到的结果。

我在视图中使用的代码是:

<div class="editor-label">
    @Html.LabelFor(model => model.Author)
</div>
<div class="editor-field">
    @Html.DropDownListFor(m => m.Author, new SelectList(new Lab2Repository().GetAuthors(), "Id", "Name"), "---- Select Category ----")
    @Html.ValidationMessageFor(m=>m.Author)
</div>
<div class="editor-label">
    @Html.LabelFor(m=>m.Category)
</div>
<div class="editor-field">
    @Html.DropDownListFor(m => m.Category, new SelectList(new Lab2Repository().GetCategories(), "Id", "Name"), "---- Select Category ----")
    @Html.ValidationMessageFor(m => m.Category)

</div>

当我运行该代码时,无论选择什么,它都会给出验证错误 enter image description here

存储库代码:

using System;
using System.Linq;
using System.Collections.Generic;
using Int422.Lab2.Data;
using System.Web;
using Int422.Lab2.Models;


public class Lab2Repository
{
    public Lab2Context Data { get; set; }
    public Lab2Repository()
    {
        Data = (Lab2Context)HttpContext.Current.Application["State"];
    }

    #region Retrieval

    public IEnumerable<Book> GetBooks()
    {
        return Data.Books;
    }
    public IEnumerable<Author> GetAuthors()
    {
        return Data.Authors.Select(obj => new Author(obj.Name) 
        { 
            Id = obj.Id, 
            Books = GetBooks().Where(b=>b.Author.Id == obj.Id).ToList() 
        });
    }

    public IEnumerable<Category> GetCategories()
    {
        return Data.Categories.Select(obj => new Category(obj.Name, obj.Description) 
        {  
            Id = obj.Id, 
            Books = GetBooks().Where(b=>b.Category.Id == obj.Id).ToList(),
        });


    } 
    #endregion
    #region Singles
    public Author GetAuthor(int id)
    {
        return GetAuthors().Where(obj => obj.Id == id).Single();
    }

    public Category GetCategory(int id)
    {
        return GetCategories().Where(obj => obj.Id == id).Single();
    }

    public Book GetBook(int id)
    {
        return Data.Books.Where(obj => obj.Id == id).Single();
    }
    #endregion
    #region Edit
    public void Edit(int id, Category rec)
    {
        if (id != rec.Id)
            throw new InvalidOperationException("Id Mismatch during edit process");

        int index = Data.Categories.IndexOf(Data.Categories.Single(p => p.Id == id));
        if (index == -1)
            throw new InvalidOperationException("Record not found no record to edit");
        Data.Categories[index] = rec;
        SaveChanges();

    }
    public void Edit(int id, Book rec)
    {
        if (id != rec.Id)
            throw new InvalidOperationException("Id Mismatch during edit process");

        int index = Data.Books.IndexOf(Data.Books.Single(p => p.Id == id));
        if (index == -1)
            throw new InvalidOperationException("Record not found no record to edit");
        Data.Books[index] = rec;
        SaveChanges();
    }


    public void Edit(int id, Author rec)
    {
        if (id != rec.Id)
            throw new InvalidOperationException("Id Mismatch during edit process");

        int index = Data.Authors.IndexOf(Data.Authors.Single(p => p.Id == id));
        if (index == -1)
            throw new InvalidOperationException(String.Format("Record id {0} not found", id));
        Data.Authors[index] = rec;
        SaveChanges();

    }
    #endregion
    #region Create
    //
    public int Create(Category m)
    {
        m.Id = Data.Categories.Max(o => o.Id) + 1;
        Data.Categories.Add(m);
        SaveChanges();
        return m.Id;

    }

    //adds new author to the collection returns the id 
    public int Create(Author m)
    {
        m.Id = Data.Authors.Max(o => o.Id) + 1;
        Data.Authors.Add(m);
        SaveChanges();
        return m.Id;
    }

    public int Create(Book m)
    {
        m.Id = Data.Authors.Max(o => o.Id) + 1;
        Data.Books.Add(m);
        SaveChanges();
        return m.Id;
    }
    #endregion
    #region Delete

    public void Delete(Author rec)
    {
        Data.Authors.Remove(Data.Authors.Single(o => o.Id == rec.Id));
        SaveChanges();
    }

    public void Delete(Category m)
    {
        Data.Categories.Remove(Data.Categories.Single(o => o.Id == m.Id));
        SaveChanges();
    }

    public void Delete(Book m)
    {
        Data.Books.Remove(Data.Books.Single(o => o.Id == m.Id));
        SaveChanges();
    }





    #endregion
    #region Session Persistance

    public void SaveChanges()
    {
        //save to session 
        HttpContext.Current.Application["State"] = Data;
        //refresh repo state from session 
        Data = (Lab2Context)HttpContext.Current.Application["State "];
    }

    #endregion




}

型号:

    public class Author
    {
        public Author(string name)
        {
            Name = name;
        }
        public Author()
        {
            Books = new List<Book>();
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<Book> Books { get; set; }

    }

public class Category
    {

        public Category(string name, string desc)
        {
            Name = name;
            Description = desc;
            Books = new List<Book>();
        }
        public Category()
        {

        }
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public virtual ICollection<Book> Books  { get; set; }

    }

public class Book
    {
        public Book(string title, Author author, Category category, double retailPrice, double cost)
        {
            Title = title;
            Author = author;
            Category = category;
            RetailPrice = retailPrice;
            Cost = cost; 
        }
        public Book()
        {

        }

        public int Id { get; set; }
        public Category Category { get; set; }
        public Author Author { get; set; }
        public string Title { get; set; }
        public double RetailPrice { get; set; }
        public double Cost { get; set; }

    }

控制器:

public partial class BooksController : Controller
    {
        private Lab2Repository repo = new Lab2Repository();

        //
        // GET: /Books/

        public virtual ViewResult Index()
        {
            return View(repo.GetBooks());
        }

        //
        // GET: /Books/Details/5
        [GET("Books/{id:int}")]
        public virtual ActionResult Details(int id)
        {
            Book book = repo.GetBook(id);
            return View(book);
        }

        //
        // GET: /Books/Create

        public virtual ActionResult Create()
        {
            return View();
        } 

        //
        // POST: /Books/Create

        [HttpPost]
        public virtual ActionResult Create(Book book)
        {
            if (!ModelState.IsValid)
                return View(book);

            repo.Create(book);

            return RedirectToAction(MVC.Books.Index());

        }

        //
        // GET: /Books/Edit/5

        public virtual ActionResult Edit(int id)
        {
            Book book = repo.GetBook(id);
            return View(book);
        }

        //
        // POST: /Books/Edit/5

        [HttpPost]
        public virtual ActionResult Edit(int id, Book book)
        {
            if (!ModelState.IsValid)
                return View(book);

            repo.Edit(id, book);

            return RedirectToAction(MVC.Books.Details(id));
        }

        //
        // GET: /Books/Delete/5

        public virtual ActionResult Delete(int id)
        {
            Book book = repo.GetBook(id);
            return View(book);
        }

        //
        // POST: /Books/Delete/5

        [HttpPost, ActionName("Delete")]
        public virtual ActionResult DeleteConfirmed(int id)
        {
            Book book = repo.GetBook(id);
            repo.Delete(book);

            return RedirectToAction("Index");
        }


    }

初​​始化器:

public class Lab2StoreInitializer
{
public void Seed(Lab2Context c)
{

    //add categories 
    var cat_Programming = new Category("Programming", "Books about writing computer code and developing software") { Id = 1 };
    var cat_Politics = new Category("Politics", "books with politically charged subjects") { Id = 2 };
    var cat_NonFiction = new Category("Non-Fiction", "Books about real life events") { Id = 3 };


    c.Categories.Add(cat_Programming);
    c.Categories.Add(cat_Politics);
    c.Categories.Add(cat_NonFiction);


    //add authors 
    var noamChomsky = new Author("Noam Chomsky") { Id = 1};
    var howardZinn = new Author("Howard Zinn") { Id = 2 };
    var scottHanselman = new Author("Scott Hanselman") { Id = 3 };
    var philHaack = new Author("Phil Haack") { Id = 4 };
    var danielleSteele = new Author("Danielle Steele") { Id = 5 };
    var johnSkeet = new Author("John Skeet") { Id = 6 };
    var johnResig = new Author("John Resig") { Id = 7 };
    var scottKlein = new Author("Scott Klein") { Id = 8 };


    c.Authors.Add(noamChomsky);
    c.Authors.Add(howardZinn);
    c.Authors.Add(scottHanselman);
    c.Authors.Add(philHaack);
    c.Authors.Add(danielleSteele);
    c.Authors.Add(johnSkeet);
    c.Authors.Add(johnResig);
    c.Authors.Add(scottKlein);

    // add books 

    c.Books.Add(new Book("Manufacturing Consent", noamChomsky, cat_Politics, 16.57, 12.00) { Id = 1 });
    c.Books.Add(new Book("The Zinn Reader", howardZinn, cat_Politics, 35.75, 30.00) { Id = 2 });
    c.Books.Add(new Book("C# In Depth", johnSkeet, cat_Programming, 29.99, 25.00) { Id = 3 });
    c.Books.Add(new Book("Professional ASP.NET MVC 2", scottHanselman, cat_Programming, 34.99, 30.00) { Id = 4 });
    c.Books.Add(new Book("Professional MVC 4", philHaack, cat_Programming, 49.99, 45.00) { Id = 5 });
    c.Books.Add(new Book("His Bright Light: The Story of Nick Traina", danielleSteele, cat_NonFiction, 19.99, 14.00) { Id = 6 });
    c.Books.Add(new Book("Secrets of the JavaScript Ninja", johnResig, cat_Programming, 34.99, 29.99) { Id = 7 });
    c.Books.Add(new Book("Professional LINQ", scottKlein, cat_Programming, 39.99, 35.00) { Id = 8 });
    c.Books.Add(new Book("jQuery in Action", johnResig, cat_Programming, 49.99, 43.00) { Id = 9 });


    HttpContext.Current.Application["State"] = c;
    //base.Seed(c);
}
}

2 个答案:

答案 0 :(得分:5)

@Html.DropDownListFor(m => m.Author.Id, new SelectList(new Lab2Repository().GetAuthors(), "Id", "Name"), "---- Select Category ----")

答案 1 :(得分:0)

SelectList正在使用Id的{​​{1}}属性在Author中识别它。但是,您的Book模型将其定义为:

Book

默认模型绑定器不知道如何将public Author Author { get; set; } Id相关联。要解决此问题,您可以这样声明:

Author

由于public int Author { get; set; } Id现在是相同的数据类型(Author),因此它会起作用。 int

也是如此
Category

您的选择是编写自己的模型绑定器并将其注册到MVC。然后,当从下拉列表中仅传递public int Category { get; set; } 时,您可以强制它加载整个Author对象。请参阅此问题以获得一些建议:ASP.Net MVC Custom Model Binding explanation