Отправка значения DropDownList из представления в контроллер в MVC4
У меня есть приложение MVC4, и, хотя у меня есть параметры для моего DropDownList из базы данных, я сталкиваюсь с какими-то проблемами при публикации значения DropDownList в базе данных. Существует множество примеров для другого подхода, но я хотел бы применить метод без использования дополнительного подхода, например Ajax, Javascript и т. Д. С другой стороны, я столкнулся с "FormCollection" для передачи данных, но я не уверен Если FormCollection является лучшим способом в этой сцене. Вот некоторая часть вида, контроллера и модели, которую я использую:
Посмотреть:
@using (Html.BeginForm("Add", "Product", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<p>Product Type : @Html.DropDownListFor(m => m.SelectedLookupId, new SelectList(Model.Lookups.Where(x => x.LookupType == "Product Type"), "LookupID", "LookupValue"), "--- Select ---") </p>
контроллер:
[HttpPost]
public ActionResult Add(Product product)
{
if (ModelState.IsValid)
{
product.ProductType = // ??? Cannot get the SelectedLookupId
...
repository.SaveProduct (product);
TempData["message"] = string.Format("{0} has been saved", product.Name);
return View("Completed");
}
else
{
//there is something wrong with the data values
return View(product);
}
}
ViewModel:
public class ProductViewModel
{
public IEnumerable<Product> Products { get; set; }
public IEnumerable<Lookup> Lookups { get; set; } //Lookup for Product Types
public int SelectedLookupId { get; set; }
public Product Product { get; set; }
}
Заранее спасибо за вашу помощь.
2 ответа
Спасибо за ответ. На самом деле, используя ViewModel, а не View, мне удалось решить эту проблему. С другой стороны, после некоторых исследований я применил еще один эффективный метод для заполнения Dropdownlist без необходимости использования ViewModel. Кроме того, в этом примере я мог бы использовать несколько внешних ключей в одной таблице поиска, как показано ниже. Здесь представлен объект " Заявитель", имеющий 3 внешних ключа и объект " Поиск", связанный с этими ключами. В этом примере я хотел добиться именно того, чтобы использовать таблицу поиска только для нескольких параметров Dropdownlist, например, Gender, Yes/No, Status,... из-за того, что нет необходимости создавать таблицу для нескольких параметров (эти параметры различаются LookupType свойство в таблице поиска). Вот полный пример (для краткости я сократил несвязанные свойства):
Заявитель
public class Applicant
{
[Key]
public int ApplicantID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
// for using "Multiple foreign keys within same table using Fluent API"
public int? HasDoneAnyProject { get; set; }
public int? IsInterestedAnyProgramme { get; set; }
public int? InterestedProgrammeId { get; set; }
public virtual Lookup PrimaryLookup { get; set; }
public virtual Lookup SecondaryLookup { get; set; }
public virtual Lookup TertiaryLookup { get; set; }
}
Поиск объекта:
public class Lookup
{
[Key]
public int LookupID { get; set; }
public string LookupType { get; set; }
public string LookupValue { get; set; }
// for using "Multiple foreign keys within same table using Fluent API"
public virtual ICollection<Applicant> PrimaryLookupFor { get; set; }
public virtual ICollection<Applicant> SecondaryLookupFor { get; set; }
public virtual ICollection<Applicant> TertiaryLookupFor { get; set; }
}
DbContext:
public class EFDbContext : DbContext
{
public DbSet<Applicant> Applicants { get; set; }
public DbSet<Lookup> Lookups { get; set; }
//for using "Multiple foreign keys within same table using Fluent API"
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Applicant>()
.HasOptional(b => b.PrimaryLookup)
.WithMany(a => a.PrimaryLookupFor)
.HasForeignKey(b => b.HasDoneAnyProject)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Applicant>()
.HasOptional(b => b.SecondaryLookup)
.WithMany(a => a.SecondaryLookupFor)
.HasForeignKey(b => b.IsInterestedAnyProgramme)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Applicant>()
.HasOptional(b => b.TertiaryLookup)
.WithMany(a => a.TertiaryLookupFor)
.HasForeignKey(b => b.InterestedProgrammeId)
.WillCascadeOnDelete(false);
}
}
контроллер:
private void PopulateLookupsDropDownList(string lookupType, string foreignKey, object selectedLookups = null)
{
var lookupsQuery = repository.Lookups
.Select(x => x)
.Where(x => x.LookupType == lookupType)
.OrderBy(x => x.ParentLookupID).ToList();
ViewData[foreignKey] = new SelectList(lookupsQuery, "LookupID", "LookupValue", selectedLookups);
}
и для вызова метода для каждого из трех выпадающих списков:
PopulateLookupsDropDownList("YesNo", "HasDoneAnyProject", applicant.HasDoneAnyProject);
PopulateLookupsDropDownList("YesNo", "IsInterestedAnyProgramme", applicant.IsInterestedAnyProgramme);
PopulateLookupsDropDownList("Programme", "InterestedProgrammeId", applicant.InterestedProgrammeId);
View:: заполнение каждого из трех выпадающих списков из одной и той же таблицы поиска с другим параметром LookupType:
<label>Has done any project before?</label>
@Html.DropDownList("HasDoneAnyProject", "---- Select ----")
<label>Are you interested in any programme?</label>
@Html.DropDownList("IsInterestedAnyProgramme", "---- Select ----")
<label>Interested programme name?</label>
@Html.DropDownList("InterestedProgrammeId", "---- Select ----")
Я надеюсь, что этот подход будет полезен для тех, кто хочет заполнить выпадающие списки из одной таблицы поиска. С другой стороны, он не только подходит для этого, но также может использоваться для заполнения выпадающих списков из разных таблиц.
С уважением.
Ваш метод действия должен получать модель представления, а не сам Продукт, например:
[HttpPost]
public ActionResult Add(ProductViewModel productViewModel)
Если я не запутался. Но я предполагаю, что фрагмент представления, который вы разместили выше, взят из представления Add, и модель этого вида имеет тип ProductViewModel
, В вашем методе действия вы возвращаете представление Add, когда состояние модели недопустимо, однако вы передаете Product
к этому мнению. Снова я могу быть смущен, потому что это должно дать вам ошибку времени выполнения, что типы не совпадают.