我使用数据库表中的值填充了一个下拉列表。列表中填充了正确的表数据,但所有值在列表中都有ZERO索引。以下是填写下拉列表的代码:
//Get
public ActionResult NewBooking()
{
var db = new VirtualTicketsDBEntities2();
IEnumerable<SelectListItem> items = db.Attractions
.ToList()
.Select(c => new SelectListItem
{
Value = c.A_ID.ToString(),
Text = c.Name
});
ViewBag.Attractions = items;
return View();
}
在下拉视图页面上:
<div class="editor-label">
@Html.LabelFor(model => model.Attraction)
</div>
<div class="editor-field">
@Html.DropDownList("Attractions")
</div>
例如,如果表有3个值A,B和C.这些值出现在下拉列表中,但是当我在POST请求函数中获取其选定的索引时,它总是返回ZERO。这是POST提交功能:
//Post
[HttpPost]
public ActionResult NewBooking(BookingView booking)
{
try
{
BookingManager bookingManagerObj = new BookingManager();
bookingManagerObj.Add(booking);
ViewBag.BookingSavedSucess = "Booking saved!";
return View("WelcomeConsumer","Home");
}
catch
{
return View(booking);
}
}
booking.Attraction
即使用户选择的大于ZERO索引项也始终为零。
有什么建议吗?
答案 0 :(得分:1)
我猜这是因为你得到的是SelectListItems
的集合,而不是实际的SelectList
。尝试类似:
<div class="editor-field">
@Html.DropDownListFor(model => model.Attraction, new SelectList(ViewBag.Attractions, "Value", "Text");
答案 1 :(得分:0)
最好不要使用ViewBag
,您应该始终使用ViewModel
。
假设你有ViewModel
这样:
public class AttractionViewModel
{
public int AttractionId { get; set; }
public SelectList Attractions { get; set; }
}
并修改你的视图 - 我假设你已经有一个表单,相关位是@Html.DropDownListFor(...)
并确保你有一个完整的命名空间到ViewModel,如果你还没有包含它视图web.config文件:
@model AttractionViewModel
@using(Html.BeginForm("NewBooking", "ControllerName"))
{
<div class="editor-label">
@Html.LabelFor(model => model.AttractionId)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.AttractionId, Model.Attractions)
</div>
<input type="submit" value="Submit">
}
并像这样修改HttpGet
:
//Get
public ActionResult NewBooking()
{
var db = new VirtualTicketsDBEntities2();
var items = db.Attractions.ToList();
var attractionIdDefault = 0;// default value if you have one
var vm = new AttractionViewModel {
AttractionId = attractionIdDefault,// set this if you have a default value
Attractions = new SelectList(items, "A_ID", "Name", attractionIdDefault)
}
return View(vm);
}
并创建HttpPost
ActionResult
,如下所示:
// Post
public ActionResult NewBooking(AttractionViewModel vm)
{
var attractionId = vm.AttractionId; // You have passed back your selected attraction Id.
return View();
}
然后它应该工作。
答案 2 :(得分:0)
我知道你已经选择了你的答案,但这是你做的事情的另一种方式。当我开始使用ASP.NET MVC
时,我与SelectListItem
进行了斗争,并找到了另一种填充下拉列表的方法。从那时起我一直坚持这种方式。
我总是有一个视图模型,我绑定到我的视图。我从不通过域模型发送,始终是视图模型。视图模型只是域模型的缩小版本,可以包含来自多个域模型的数据。
我对您的代码和提示进行了一些修改,但正如我所提到的,它只是您已有的替代方案。
您的域名模型可能如下所示。尝试给你的属性名称一些有意义的描述:
public class Attraction
{
public int Id { get; set; }
public string Name { get; set; }
}
您查看的模型可能如下所示:
public class BookingViewModel
{
public int AttractionId { get; set; }
public IEnumerable<Attraction> Attractions { get; set; }
// Add your other properties here
}
您的控制器中没有数据访问方法,而是让服务层或存储库公开此功能:
public class BookingController : Controller
{
private readonly IAttractionRepository attractionRepository;
public BookingController(IAttractionRepository attractionRepository)
{
this.attractionRepository = attractionRepository;
}
public ActionResult NewBooking()
{
BookingViewModel viewModel = new BookingViewModel
{
Attractions = attractionRepository.GetAll()
};
return View(viewModel);
}
[HttpPost]
public ActionResult NewBooking(BookingViewModel viewModel)
{
// Check for null viewModel
if (!ModelState.IsValid)
{
viewModel.Attractions = attractionRepository.GetAll();
return View(viewModel);
}
// Do whatever else you need to do here
}
}
然后你的观点将填充你的下拉:
@model YourProject.ViewModels.Attractionss.BookingViewModel
@Html.DropDownListFor(
x => x.AttractionId,
new SelectList(Model.Attractions, "Id", "Name", Model.AttractionId),
"-- Select --"
)
@Html.ValidationMessageFor(x => x.AttractionId)
我希望这会有所帮助。