2009-05-30 105 views
2

我有一个注册表单,它显示用户名(文本框),电子邮件(文本框)和分区(SelectList)。名称和电子邮件预先填充(我正在使用Windows身份验证,Intranet应用程序),并且我想将DropDown中的SelectedValue作为Int32发送到我的控制器,我不想将整个SelectList发送回去。这份名单现在很小,但会增长到相当的规模。将SelectList“SelectedValue”传递给控制器​​操作方法

我是一个叫RegistrationViewModel的类,它包含这些字段的公共属性。但是,当我使用SelectList作为DivisionList时,我收到此错误:No parameterless constructor defined for this object.

如果我改变类型,它没有问题,但分区为空或0.有没有一种方法来将DropDown作为Int32传递给控制器​​Action方法的SelectedValue?

编辑1:

我真的不知道我在做什么,我一直在使用MVC约48小时,观看PDF,微软技术大会,并TechDays视频。

我的道歉,这是我的控制器代码:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Register(RegistrationViewModel rvm) 
{ 
    IApplicationContext context = ContextRegistry.GetContext(); 
    IValidationErrors errors = new ValidationErrors(); 

    IValidator validator = (IValidator)context.GetObject("RegistrationValidator"); 
    bool valid = validator.Validate(rvm, errors); 

    if (valid) 
     repo.SaveRegistration(); 
    else 
     ViewData["DivisionList"] = repo.GetDivisions(); 

    return View(rvm); 
} 

RegistrationViewModel

public class RegistrationViewModel 
{ 
    public string Name { get; set; } 
    public string Email { get; set; } 
    //public SelectList DivisionList { get; private set; } 
    public int Division { get; set; }  
} 

这里的景色

<%@ Page Language="C#" 
MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<RegistrationViewModel>" %> 

<%@ Import Namespace="Project1.Entities"%> 
<%@ Import Namespace="Project1.Models"%> 

<asp:Content ID="registerTitle" ContentPlaceHolderID="TitleContent" runat="server"> 
    Register 
</asp:Content> 

<asp:Content ID="registerContent" ContentPlaceHolderID="MainContent" runat="server"> 
... 
    <% using (Html.BeginForm()) 
     { %> 
     <div> 
      <fieldset> 
       <legend>Account Information</legend> 
       <p> 
        <label for="name">Name:</label> 
        <%= Html.TextBox("Name", User.Identity.Name.GetDisplayName()) %> 
        <%= Html.ValidationMessage("username") %> 
       </p> 
       <p> 
        <label for="email">Email:</label> 
        <%= Html.TextBox("email", User.Identity.Name.GetEmailFromLogin()) %> 
        <%= Html.ValidationMessage("email") %> 
       </p>    
       <p> 
        <label for="division">Division:</label> 
        <%= Html.DropDownList("DivisionList", ViewData["DivisionList"] as SelectList)%> 
        <%= Html.ValidationMessage("confirmPassword") %> 
       </p> 
       <p>     
        <input type="submit" value="Register" /> 
       </p> 
      </fieldset> 
     </div> 
    <% } %> 
</asp:Content> 

编辑2:

Eilon:在这里,我是我改变了它太:

控制器:

public ActionResult Register() 
{ 
    ViewData["DivisionList"] = repo.GetDivisions(); 
    return View(); 
} 

查看:

<%= Html.DropDownList("DivisionValue", ViewData["DivisionList"] as SelectList)%> 

我收到此异常: 有型的关键 'DivisionValue' 没有ViewData的项目“的IEnumerable ”。

当我查看更新到这一点:

<%= Html.DropDownList("DivisionList", ViewData["DivisionList"] as SelectList)%> 

它的工作好了!如果所有的“部门”项目命名相同,似乎只能起作用。如果我更改名称,视图崩溃或ViewModel“Division”属性发送为0.

为什么?

+0

请告诉我们您的控制器动作的代码。你如何传递电子邮件文本框的价值? – ichiban 2009-05-30 20:53:14

回答

5

RegistrationViewModel类型应包含一个简单类型的属性,如:

public string DivisionValue { get; set; } 

或改变类型为int,日期时间,或任何适当的类型。

在HTML和HTTP中,返回下拉列表的唯一内容是字段名称和所选值。

要得到的一切来匹配您还需要改变的观点来呈现不同的输入名称下拉列表:

<%= Html.DropDownList("DivisionValue", ViewData["DivisionList"] as SelectList)%> 

请注意,我使用“DivisionValue”是DivisionList作为所有可用项目的列表。

0

我只是更加明确SelectList类型。我建议在控制器操作中创建SelectList,并忘记在视图中投射它。我的代码是这样的(CRUD编辑页面):

..in行动:

  ViewData["WorkType.ID"] = new SelectList(this._vacancySvc.GetVacancyWorkTypes(), 
      "ID", "Name", ViewData["WorkType.ID"] ?? vacancy.WorkType.ID); 

..和视图:

<p><% =Html.Encode("Work Type:") %><br /> 
      <% =Html.DropDownList("Worktype.ID")%><span class="smallgrey">(required)</span><br /> 

..你可以看到,无论是通过使用[null coalescing operator] [1](??),初始选择(来自数据库)被持久化或Viewback从后发布(如果表单未通过验证)。

而且,如果我重构这个代码,我喜欢的概率像你使用一个ViewModel对象。 唯一的一点是:(1)你永远需要引用视图中的堂妹MVC自动视图模型SelectList属性由Html.DropDownList()超载结合这对我们来说..(2)我仍然需要参考的ViewData的中无论如何,从一个失败的验证帖子中获得选定的值的动作,所以真的有什么意义?

相关问题