我是一名初学者程序员,在使用 @Html.DropDownListFor 助手时遇到了麻烦...
我正在使用基于此处教程的通用存储库和工作单元模式: http ://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository- and-unit-of-work-patterns-in-an-asp-net-mvc-application
这是我的存储库代码:
public class GenericRepository<TEntity> where TEntity : class
{
internal UsersContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(UsersContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
// Delete methods not shown
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
这是我的 UnitOfWork 类的代码:
public class UnitOfWork : IDisposable
{
private UsersContext context = new UsersContext();
private GenericRepository<UserProfile> userProfileRepository;
private GenericRepository<Lead> leadRepository;
private GenericRepository<UnitedStatesState> unitedStatesStateRepository;
public GenericRepository<UserProfile> UserProfileRepository
{
get
{
if (this.userProfileRepository == null)
{
this.userProfileRepository = new GenericRepository<UserProfile(context);
}
return userProfileRepository;
}
}
public GenericRepository<Lead> LeadRepository
{
get
{
if (this.leadRepository == null)
{
this.leadRepository = new GenericRepository<Lead>(context);
}
return leadRepository;
}
}
public GenericRepository<UnitedStatesState> UnitedStatesStateRepository
{
get
{
if (this.unitedStatesStateRepository == null)
{
this.unitedStatesStateRepository = new GenericRepository<UnitedStatesState>(context);
}
return unitedStatesStateRepository;
}
}
我正在尝试使用强类型视图和模型,以便在不使用 ViewData/ViewBag 的情况下将选择列表数据传递给视图。据我了解,最好的做法是做一些类似于我在这里看到的事情: validate a dropdownlist in asp.net mvc
我尝试尽可能地遵循这一点,这就是我想出的
我的视图模型如下所示:
public class Lead
{
public int LeadID { get; set; }
public int CompanyID { get; set; }
[Required(ErrorMessage = "Please enter state")]
[Display(Name = "State")]
[MaxLength(2)]
public string State { get; set; }
[Display(Name = "Assigned To")]
public string AssignedTo { get; set; }
[Timestamp]
public Byte[] Timestamp { get; set; }
public virtual Company Company { get; set; }
// IEnumerables for Dropdown Lists passed to views
public IEnumerable<UnitedStatesState> UnitedStatesStates { get; set; }
public IEnumerable<UserProfile> UserProfiles { get; set; }
// Objects passed to views
public Lead lead { get; set; }
}
然后,我的下拉列表的这些 IEnumerables 从我的数据库通过我的存储库填充到我的控制器中。奇怪的是,我在两个不同的视图中使用这些下拉列表,创建和编辑。当我在 Create 视图中使用下拉列表时,它们在 GET 和 POST ActionResults 上都能完美运行。当我尝试为我的编辑视图使用相同的下拉列表时,它们适用于 GET ActionResult(视图加载和下拉列表工作)但是当我尝试将它们发布到我的编辑 ActionResult 时,我收到以下错误:
{"Value cannot be null.\r\nParameter name: items"} // 这是 Visual Studio 2012 中显示的错误
System.ArgumentNullException:值不能为空。参数名称:items //这是谷歌浏览器中显示的错误
下面是我的主控制器,带有编辑和创建操作结果:
public class LeadController : Controller
{
// create instance of Repository Unit of Work
private UnitOfWork unitOfWork = new UnitOfWork();
public ActionResult Create()
{
// Get the current users profile
UserProfile userProfile = UserProfile.GetCurrentUserProfile();
// Creates Dropdown Lists to pass to view
var model = new Lead
{
UnitedStatesStates = unitOfWork.UnitedStatesStateRepository.Get(u => u.StateAbbreviation != null),
UserProfiles = unitOfWork.UserProfileRepository.Get(u => u.CompanyID == userProfile.CompanyID)
};
// Return View
return View(model);
}
[HttpPost]
public ActionResult Create(Lead model)
{
try
{
if (ModelState.IsValid)
{
// Call the current users profile
UserProfile userProfile = UserProfile.GetCurrentUserProfile();
// Create a new lead and apply all attirbutes that were entered
Lead lead = new Lead();
lead.CompanyID = userProfile.CompanyID;
lead.State = model.State;
lead.AssignedTo = model.AssignedTo;
// Add the lead and save the changes. Redirect to Lead Index.
unitOfWork.LeadRepository.Insert(lead);
unitOfWork.Save();
return RedirectToAction("Index");
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes. Try again and if the problem persists, see your system administrator.");
}
// Return view if ModelState is not valid
return View();
}
public ActionResult Edit(int id = 0)
{
// Get Users Profile
UserProfile userProfile = UserProfile.GetCurrentUserProfile();
// Check to see if Lead Exists
if (unitOfWork.LeadRepository.GetByID(id) == null)
{
return HttpNotFound();
}
// Creates Dropdown Lists and Gets current lead values to pass to view
var model = new Lead
{
lead = unitOfWork.LeadRepository.GetByID(id),
UnitedStatesStates = unitOfWork.UnitedStatesStateRepository.Get(u => u.StateAbbreviation != null),
UserProfiles = unitOfWork.UserProfileRepository.Get(u => u.CompanyID == userProfile.CompanyID)
};
return View(model);
}
[HttpPost]
public ActionResult Edit(Lead lead)
{
try
{
// Update lead if model state is valid
if (ModelState.IsValid)
{
unitOfWork.LeadRepository.Update(lead);
unitOfWork.Save();
return RedirectToAction("Index");
}
}
// Catch any concurrency exceptions
catch (DbUpdateConcurrencyException ex)
{
var entry = ex.Entries.Single();
var databaseValues = (Lead)entry.GetDatabaseValues().ToObject();
var clientValues = (Lead)entry.Entity;
if (databaseValues.State != clientValues.State)
ModelState.AddModelError("State", "Current value: "
+ databaseValues.State);
if (databaseValues.AssignedTo != clientValues.AssignedTo )
ModelState.AddModelError("Assigned To ", "Current value: "
+ databaseValues.AssignedTo );
ModelState.AddModelError(string.Empty, "The record you attempted to edit "
+ "was modified by another user after you got the original value. The "
+ "edit operation was canceled and the current values in the database "
+ "have been displayed. If you still want to edit this record, click "
+ "the Save button again. Otherwise click the Back to List hyperlink.");
lead.Timestamp = databaseValues.Timestamp;
}
catch (DataException)
{
//Log the error (add a variable name after Exception)
ModelState.AddModelError(string.Empty, "Unable to save changes. Try again, and if the problem persists contact your system administrator.");
}
// Return View if Model State is not valid
return View(lead);
}
POST Edit ActionResult 包括用于捕获我按照此处显示的教程创建的并发代码: http ://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with- asp-net-mvc 应用程序中的实体框架
以下是我对 Create 的看法(效果很好):
@model SolarToolbase.Models.Lead
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<div>
<div>
@Html.LabelFor(model => model.State)
@Html.DropDownListFor(model => model.State, new SelectList(Model.UnitedStatesStates, "StateAbbreviation", "UnitedStatesStateName"),"Choose State")<br />
@Html.ValidationMessageFor(model => model.State)
</div>
<div>
@Html.LabelFor(model => model.AssignedTo)
@Html.DropDownListFor(model => model.AssignedTo, new SelectList(Model.UserProfiles, "FullName", "FullName"),"Choose User")<br />
@Html.ValidationMessageFor(model => model.AssignedTo)
</div>
<p>
<input type="submit" value="Create" />
</p>
</div>
}
下面是我对编辑的看法(当我点击提交按钮时,这会引发上述错误。我在下面插入了一条评论以显示引发错误的行):
@model SolarToolbase.Models.Lead
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.lead.LeadID)
@Html.HiddenFor(model => model.lead.Timestamp)
<div>
<div>
@Html.LabelFor(model => model.lead.State)
@Html.DropDownListFor(model => model.lead.State, new SelectList(Model.UnitedStatesStates, "StateAbbreviation", "UnitedStatesStateName"))<br /> // Error thrown from this line
@Html.ValidationMessageFor(model => model.lead.State)
</div>
<div>
@Html.LabelFor(model => model.lead.AssignedTo)
@Html.DropDownListFor(model => model.lead.AssignedTo, new SelectList(Model.UserProfiles, "FullName", "FullName"))<br />
@Html.ValidationMessageFor(model => model.lead.AssignedTo)
</div>
<p>
<input type="submit" value="Save" />
</p>
</div>
}
我提前为发布这么多代码而道歉,老实说,我不知道这个错误来自哪里,我已经把头撞在墙上试图弄清楚大约 4 个小时。任何可以提供帮助的人都可以免费虚拟击掌和良好的因果报应。
谢谢!