所有下拉项目都有ZERO索引MVC3

时间:2013-07-18 17:21:23

标签: c# asp.net-mvc-3 visual-studio-2012

我使用数据库表中的值填充了一个下拉列表。列表中填充了正确的表数据,但所有值在列表中都有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索引项也始终为零。

有什么建议吗?

3 个答案:

答案 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)

我希望这会有所帮助。