【问题标题】:drop down list value is null after posting to controller in ASP.NET MVC在 ASP.NET MVC 中发布到控制器后下拉列表值为空
【发布时间】:2016-09-07 02:54:00
【问题描述】:

我是 ASP.NET MVC 的新手。我有一个带有提交按钮和 html 选择元素的简单表单,其中填充了两个项目。当表单发布到我的控制器时,所有表单值都为空。我什至尝试使用 $.POST 来代替,当它到达控制器时,我发送的 id 变量为空。这是我的代码:

HTML

 @using (Html.BeginForm("SetOptionForUser", "MyController", FormMethod.Post, new { @class="form-inline" }))
{
    @Html.AntiForgeryToken() 
    <div class="text-center">
        <div class="form-group">
            <select id="ddlSelect" class="form-control">
                @foreach (var item in Model.Persons)
                {
                    <option value="@item.Id">@item.Name</option>
                }
            </select>
        </div>
        <button type="submit" class="btn btn-primary" id="btnEnter">Go</button>
    </div>
}

MVC 控制器

[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult SetOptionForUser(FormCollection form)
    {
        string option = form["ddlSelect"].ToString(); //null error
        return RedirectToAction("AnotherAction", "AnotherController");
    }

似乎没有发送表单中的任何内容。我也试过这个:

JS

$("#btnEnter").click(function (e) {
    var optionId = $("#ddlSelect").val(); //this get val correctly
    $.post(@Url.Action("SetOptionForUser", "MyController"), optionId);
  });

JS方法的MVC控制器

**MVC Controller**

[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult SetOptionForUser(int optionId) //null
    {
        string option = optionId.ToString(); //null error
        return RedirectToAction("AnotherAction", "AnotherController");
    }

我做错了什么?

【问题讨论】:

    标签: c# jquery asp.net-mvc forms


    【解决方案1】:

    普通表单提交

    如果您的选择元素名称和您的 http post action 方法参数名称相同,您的普通表单提交应该可以工作。

    <select name="selectedPerson" id="selectedPerson" class="form-control">
      <!-- Options goes here --> 
    </select>
    

    和你的行动方法

    [HttpPost]
    public ActionResult SetOptionForUser(string selectedPerson)
    {
        string option = selectedPerson;
        return RedirectToAction("AnotherAction", "AnotherController");
    }
    

    您还可以考虑使用 Html.DropDownListForHtml.DropDownList 辅助方法从项目列表生成 SELECT 元素(而不是手动编写循环来呈现选项项目)。

    使用 Ajax 发送数据

    现在,如果您希望它被 ajaxified,您可以在查询字符串或请求正文中发送数据

    $(function(){
      $("#btnEnter").click(function (e) {
        e.preventDefault();
        var optionId = $("#selectedPerson").val(); 
        $.post('@Url.Action("SetOptionForUser", "MyController")', { selectedPerson:optionId});
      });
    });
    

    现在没有必要为 ajax 调用返回 RedirectResult。您可以考虑从您的操作方法返回一个 json 响应(指示您的操作是否成功),并在 $.post 的成功回调中检查该值并执行所需操作。

    [HttpPost]
    public ActionResult SetOptionForUser(string selectedPerson)
    {
        string option = selectedPerson;
        return Json(new {status="success"});
    }
    

    你可以在回调中查看响应

     var optionId = $("#selectedPerson").val();
     var url="@Url.Action("SetOptionForUser", "MyController")";
     $.post(url, { selectedPerson:optionId}, function(response){
       if(response.status==="success")
       {
          alert("Success");
       }
       else
       {
         alert("Some trouble!");
       }
     });
    

    【讨论】:

      【解决方案2】:

      我发现您的代码中唯一缺少的是下拉列表的 name 属性。

         <select id="ddlSelect" name="ddlSelect" class="form-control">
                  @foreach (var item in Model.Persons)
                  {
                      <option value="@item.Id">@item.Name</option>
                  }
              </select>
      

      对于您使用 FormCollection 的第一个示例

      string option = form["ddlSelect"].ToString();
      

      但是您的 DropDown 没有 name 属性,并且表单集合使用 name 属性作为参考,这就是您获得空值的原因。

      您的第二个示例也是如此,在您的参数中引用 DropDown 名称属性而不是 ID

      public ActionResult SetOptionForUser(int myDropDownName) //null
      {
          string option = myDropDownName.ToString(); //null error
          return RedirectToAction("AnotherAction", "AnotherController");
      }
      

      【讨论】:

        【解决方案3】:

        ASP.NET MVC 中的FormCollection 绑定到输入元素的name 属性,将name 属性添加到您的select HTML 元素,如下所示:

        <select id="ddlSelect" name="ddlSelect" class="form-control">
        

        注意:id 属性用于在 DOM 中查找内容,name 属性用于在表单中包含/提交的内容


        至于 JavaScript jQuery AJAX POST 问题,我认为问题在于 jQuery 智能猜测您的 optionId 是文本。您应该创建一个对象文字来保存 JSON 数据,然后将该值字符串化以发送到控制器,如下所示:

        var dataForServer = {
            optionId: optionId
        };
        
        $.post(@Url.Action("SetOptionForUser", "MyController"), 
               JSON.stringify(optionId), 
               null, 
               json);
        

        【讨论】:

          【解决方案4】:

          ASP.NET MVC 中的 FormCollection 获取输入元素的 name 属性

          所以添加这个属性name="ddlSelect"

          【讨论】:

            【解决方案5】:

            马托MK,

            请为您的模型发布代码。 通常,模型将保存您的网络表单运行所需的所有数据以及您的帖子将数据发回所需的所有数据。在您看来,您应该选择一个模型字段。您似乎有 Model.Persons,这很可能是描述人的类的可枚举。

            型号

            您没有描述您的模型,因此只显示了一个假模型,其中只有两个属性,一个用于保存列表选择的字符串和您的人员列表。希望您的 HttpGet Action 能够正确填充您的模型。

            public class MyModel 
            {
             public string ddSelect { get ; set; }
             public List<Person> Persons { get ; set; }
            }
            

            HTML(通常称为视图)

            我们明确告诉全世界这个视图使用这个模型。

            @model MyModel // Tell MVC what model we are using for this view
            @using (Html.BeginForm("SetOptionForUser", "MyController", FormMethod.Post, new { @class="form-inline" }))
                {
                @Html.AntiForgeryToken()
                <div class="text-center">
                    <div class="form-group">
                    @Html.DropDownListFor(m => m.ddSelect, Model.PersonList, new {id = "ddlSelect"})        
                    </div>
                    <button type="submit" class="btn btn-primary" id="btnEnter">Go</button>
                </div>
            }
            

            MVC 控制器 您的控制器希望您的视图返回 MyModel 类型的模型,因此会尝试将表单变量推送到模型的副本中(如果可以的话)。由于您的表单没有填写模型属性,因此您会得到空值。

            [ValidateAntiForgeryToken]
            [HttpPost]
            public ActionResult SetOptionForUser(MyModel theModel, FormsCollection collection) 
            {
                var selectedName = theModel.ddSelect;
                return RedirectToAction("AnotherAction", "AnotherController");
            }
            

            这应该会返回您从下拉列表中选择的值。注意从您的站点生成的 HTML(在浏览器中按 F12 并查看源代码)以了解 MVC 是如何工作的。一起玩比打它更容易。在上面的 POST 操作中,请参阅包含的参数集合...它包含所有表单变量。如果需要,可以通过它来查找非模型值。它不是必需的,可以删除,但是在该集合中四处寻找可以很好地了解数据在 POST 上的结构。

            希望这会有所帮助。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-04-08
              • 2014-08-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-12-15
              • 1970-01-01
              相关资源
              最近更新 更多