MVC RadioButtonFor Confusion

时间:2016-08-11 23:06:17

标签: c# asp.net-mvc

我正在观看教程视频https://www.youtube.com/watch?v=04RY04uKq2s,而我只是不了解RadioButtonFor正在发生的事情。

基本上,这个人创建了一个公司类:

public class Company
{

    public string SelectedDepartment {get; set;}


    public List<Department> Departments
    {
        get
        {
            SampleDBContext db = new SampleDBContext();
            return db.Departments.ToList();
        }
    }
}

`

好的,非常简单。他在这里使用了EntityFramework,它生成了SampleDBContext类。

然后他有一个非常简单的Index ActionMethod:

[HttpGet]
public ActionResult Index()
{
    Company company = new Company();
    return View();
}

此[HttpGet]的强类型视图:

@using (Html.BeginForm())
{
foreach (var department in Model.Departments)
{
    @Html.RadioButtonFor(m => m.SelectedDepartment, department.Id, (department.IsSelected.HasValue && department.IsSelected.Value) ? new (@checked = "checked")} : null
    @department.Name
}

<input type="submit" value="Submit" />[Resulting View][1]

最后这个HttpPost ActionMethod:

[HttpPost]
public string Index(Company company)
{
    if(string.IsNullOrEmpty(company.SelectedDepartment)
    {
        return "You selected nothing";
    }
    else
    {
        return "You selected department id: " + company.SelectedDepartment;
    }

好的,哇。该数据库有3列,Id,Name和IsSelected(位类型)。

所以,     1..HR..1     2..Payroll..NULL     3..IT..NULL

长篇大论?我希望不是。每件作品都很直接。

现在提出我的问题:

(1)RadioButtonFor()如何使用(m =&gt; m.SelectedDepartment)?就像在,为什么[HttpPost]方法检查它的字符串是空还是空?

(2)当您在方法中打印出company.SelectedDepartment的值时,您将获得该ID。这项任务在哪里举行?

3 个答案:

答案 0 :(得分:3)

您共享的代码并不遵循常见的约定,而且根本没有多大意义。

以下是样本问题的更常规方法:

公司模式

public class Company
{
    public int CompanyId {get; set;}
    public string SelectedDepartment {get; set;}
    public List<Department> DepartmentsList {get; set;}
}

部门模型

public class Department
{
    public int DepartmentId {get; set;}
    public string DepartmentName {get; set;}
}

视图

@model CompanyNamespace.Company

@using(Html.BeginForm())
{
    @Html.HiddenFor(model => model.CompanyId)

    foreach (Department department in Model.DepartmentsList)
    {
        @Html.LabelFor(model => modelItem.department)
        @Html.RadioButtonFor(model => modelItem.SelectedDepartment, department.DepartmentName)
    }

    <input type="submit" value="Submit" />
}

控制器

SampleDBContext db = new SampleDBContext();

[HttpGet]
public ActionResult Index()
{
    Company company = new Company();

    company.SelectedDepartment = null;
    company.DepartmentList = db.Departments.ToList();

    return View("Index", company);
}

[HttpPost]
public ActionResult Index(Company company)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    db.Companies.Add(company);
    db.SaveChanges();

    return RedirectToAction("Index")
}

数据库样本

+-----------+
| Companies |
+-----------+
+-----------------+--------------------------------+
| CompanyId (Int) | SelectedDepartment (VarChar20) |
+-----------------+--------------------------------+
| 1               | Clothing Department            |
| 2               | Electronics Department         |
| 3               | Furniture Department           |
+-----------------+--------------------------------+

+-------------+
| Departments |
+-------------+
+--------------------+----------------------------+
| DepartmentId (Int) | DepartmentName (VarChar20) |
+--------------------+----------------------------+
| 1                  | Clothing Department        |
| 2                  | Electronics Department     |
| 3                  | Furniture Department       |
| 4                  | Hardware Department        |
+--------------------+----------------------------+

回答你的问题......

&#34; model =&gt; modelItem.SelectedDepartment&#34;是一个lamda表达。表达式为&#34;此单选按钮将代表模型&#34;的SelectedDepartment字段。

由于视图中的所有单选按钮在模式中表示相同的SelectedDepartment字段,因此一次只能选择一个单选按钮。

所选单选按钮的值,即&#34; department.DepartmentName&#34;在我们的例子中,将发送回模型(和数据库)的值。

请注意,我们控件中的http post方法不再返回字符串。要查看数据的更改,您必须直接查看数据库。

答案 1 :(得分:1)

需要空或空字符串检查,因为如果选择了按钮,单选按钮的值仅包含在POST中。这对于复选框也是一样的,并且是Web标准本身的一部分,而不是MVC。

当MVC框架获取提交的值并使用它来实例化(POST)Index方法参数类型的新实例时,分配company.SelectDepartment的值。这是通过将提交数据中的属性名称与参数类型的属性名称进行匹配来完成的。通过将RadioButtonFor辅助方法与类型化模型一起使用,可以保证单选按钮的名称和提交值的名称与Index方法所需的类型相匹配。

答案 2 :(得分:1)

在您的视图代码中,缺少视图使用的实际模型的定义。您可以通过添加@model CompanyNamespace.Company来完成此操作。

  1. m => m.SelectedDepartment是一个lambda,它选择Model的属性,您可以在Post动作中检查该属性以检索用户选择的单选按钮的value。如果用户没有选择任何单选按钮,则该值为null(或通常为default(T),在这种情况下为default(string) = null),因此if条件为邮政行动。

  2. RadioButtonFor的第二个参数指定每个单选按钮的值。由于在您的情况下它是department.Id,因此每个生成的单选按钮的值是部门的Id。

  3. 至于代码,正如其他人已经在你的回答的评论中指出的那样,我不会真的建议你使用你发布的aproach,并可能切换到其他来源学习MVC。 IIRC,asp.net上有一些易于理解的教程。

    修改 提交表单时,请求将路由到用[HttpPost]修饰的操作,并且模型绑定器通过尝试匹配复杂对象的参数名称或属性来将发布的数据绑定到方法的参数(或参数)发布数据。因此,当用户选择一些单选按钮时,它的值(取自RadioButtonFor调用指定的department.Id)被分配给company.SelectedDepartment属性。

    扩展模型绑定的编辑受到@Jaquez answer的启发,试图提供更完整的描述,当我后来比较两者时(在OP选择此作为答案之后)在我看来,它最终 - 在很大程度上 - 作为对@Jaquez答案部分的重述。我认为这是公平的。