asp.net-mvc-3 - ViewBag 多个 SelectList 用于下拉列表

标签 asp.net-mvc-3 selectlist viewbag

我正在尝试将 dropdownList 与两个外键一起使用,这两个外键是 modelId 和 categoryId。 我将 ViewBag 与 selectList 结合使用。

public ActionResult Create()
    {
        ViewBag.categoryId = new SelectList(db.Category, "categoryId", "name");
        ViewBag.modelId = new SelectList(db.Model, "modelId", "name");
        return View();
    } 

    //
    // POST: /Product/Create

    [HttpPost]
    public ActionResult Create(Product product)
    {
        if (ModelState.IsValid)
        {
            db.Product.Add(product);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }
        ViewBag.categoryId = new SelectList(db.Category, "categoryId", "name", product.categoryId);
        ViewBag.modelId = new SelectList(db.Model, "modelId", "name", product.modelId);
        return View(product);
    }

这是我的 Create.cshtml。

<div class="editor-label">
        @Html.LabelFor(model => model.Category)
    </div>
    <div class="editor-field">
        @Html.DropDownList("categoryId", "--Select--")
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Model)
    </div>

    <div class="editor-field">
        @Html.DropDownList("modelId", "--Select--")
    </div>

当我按下提交按钮时,出现错误, '已添加具有相同键的项目' 什么是问题?模型有问题吗?

这是我的模型。

--Prodruct.cs--

public class Product
{
    [Key] public int productId { get; set; }

    [Required(ErrorMessage = "Please select category")]
    public int categoryId { get; set; }

    [Required(ErrorMessage = "Please select model")]
    public int modelId { get; set; }

    [DisplayName("Model name")]
    public String model { get; set; }

    public virtual Category Category { get; set; }
    public virtual Model Model { get; set; }
}

--Category.cs--
public class Category
{
    [Key] public int categoryId { get; set; }
    public String name { get; set; }
}

--Model.cs--
public class Model
{
    [Key] public int modelId { get; set; }
    public String name { get; set; }
}

--RentalDB.cs--
public class rentalDB : DbContext
{
    public DbSet<Product> Product { get; set; }
    public DbSet<Model> Model { get; set; }
    public DbSet<Customer> Customer { get; set; }
    public DbSet<Order> Order { get; set; }
    public DbSet<Cart> Cart { get; set; }
    public DbSet<Category> Category { get; set; }
    public DbSet<OrderDetails> OrderDetails { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

哪里错了? Create中的Index page可以获取类目数据和模型数据。但是,当我提交它时,出现错误,“已添加具有相同 key 的项目”。 你能帮我看看哪里有问题吗? 谢谢。

--添加了更多代码--

我正在使用这个 LINQ。大概这里有问题。

如何在此处添加“模型”实体?

var product = from a in db.Product.Include(a => a.Category)
                      select a;

最佳答案

这就是我会做的..

我建议您不要将域模型发送到 View ,而是为每个 View 创建一个 View 模型。这样做,您将只包含屏幕上需要的内容。

为您的创建 View 创建一个新的 View 模型:

public class ProductCreateViewModel
{
     // Include other properties if needed, these are just for demo purposes

     public string Name { get; set; }
     public string SKU { get; set; }
     public string LongDescription { get; set; }

     // This is the unique identifier of your category,
     // i.e. foreign key in your product table
     public int CategoryId { get; set; }
     // This is a list of all your categories populated from your category table
     public IEnumerable<Category> Categories { get; set; }

     // This is the unique identifier of your model,
     // i.e. foreign key in your product table
     public int ModelId { get; set; }
     // This is a list of all your models populated from your model table
     public IEnumerable<Model> Models { get; set; }
}

类别类:

public class Category
{
     public int Id { get; set; }
     public string Name { get; set; }
}

模型类:

public class Model
{
     public int Id { get; set; }
     public string Name { get; set; }
}

在您的创建 View 中,您将拥有以下内容:

@model MyProject.ViewModels.ProductCreateViewModel

@using (Html.BeginForm())
{
     <table>
          <tr>
               <td><b>Category:</b></td>
               <td>
                    @Html.DropDownListFor(x => x.CategoryId,
                         new SelectList(Model.Categories, "Id", "Name", Model.CategoryId),
                         "-- Select --"
                    )
                    @Html.ValidationMessageFor(x => x.CategoryId)
               </td>
          </tr>
          <tr>
               <td><b>Model:</b></td>
               <td>
                    @Html.DropDownListFor(x => x.ModelId,
                         new SelectList(Model.Models, "Id", "Name", Model.ModelId),
                         "-- Select --"
                    )
                    @Html.ValidationMessageFor(x => x.ModelId)
               </td>
          </tr>
     </table>

     <!-- Add other HTML controls if required and your submit button -->
}

您的创建操作方法:

public ActionResult Create()
{
     ProductCreateViewModel viewModel = new ProductCreateViewModel
     {
          // Here you do database calls to populate your dropdowns
          Categories = categoryService.GetAllCategories(),
          Models = modelService.GetAllModels()
     };

     return View(viewModel);
}

[HttpPost]
public ActionResult Create(ProductCreateViewModel viewModel)
{
     // Check that viewModel is not null

     if (!ModelState.IsValid)
     {
          viewModel.Categories = categoryService.GetAllCategories();
          viewModel.Models = modelService.GetAllModels();

          return View(viewModel);
     }

     // Mapping
     Product product = ...  // Do your mapping here

     // Insert product in database
     productService.Insert(product);

     // Return the view where you need to be
}

我还建议您使用 AutoMapper为您在域模型和 View 模型之间进行映射。我还建议您查看 Fluent Validation负责您的 View 模型验证。

希望对您有所帮助。

更新的答案

用于获取所有类别的服务可能如下所示:

public class CategoryService : ICategoryService
{
     private readonly ICategoryRepository categoryRepository;

     public CategoryService(ICategoryRepository categoryRepository)
     {
          // Check if category repository is not null, throw exception if it is

          this.categoryRepository = categoryRepository;
     }

     public IEnumerable<Category> GetAllCategories()
     {
          return categoryRepository.GetAllCategories();
     }
}

categoryRepository 由 Autofac 注入(inject).

分类服务接口(interface):

public interface ICategoryService
{
     IEnumerable<Category> GetAllCategories();
}

我目前仍然首先使用 Entity Framework 4.1 代码。

我的类别存储库:

public class CategoryRepository : ICategoryRepository
{
     MyContext db = new MyContext();

     public IEnumerable<Category> GetAllCategories()
     {
          return db.Categories
               .OrderBy(x => x.Name);
     }
}

我的类别存储库界面:

public interface ICategoryRepository
{
     IEnumerable<Category> GetAllCategories()
}

关于asp.net-mvc-3 - ViewBag 多个 SelectList 用于下拉列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10041805/

相关文章:

javascript - 将参数从 Ajax ActionLink MVC 3.0 传递给 Javascript 方法

javascript - 为什么这个 javascript 在 IE 中运行这么慢,而它所做的只是修改一个选择列表?

c# - 我的 ViewData 如何可以为空,但可以在调试器中扩展?

asp.net-mvc-3 - 可空 bool 值的复选框

asp.net-mvc-3 - 从 System.Web.Helpers.WebGrid 中呈现局部 View

asp.net-mvc - 在asp.net MVC 3中授权登录URL

c# - 将默认值设置为选择列表

security - MVC 5 ViewBag 安全

asp.net-mvc - ViewData 和 ViewBag 在哪里?