在ASP.NET MVC中发布到控制器后,下拉列表值为null

时间:2016-09-07 02:54:01

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

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

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");
    }

我做错了什么?

5 个答案:

答案 0 :(得分:2)

正常表单提交

如果您的选择元素名称和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!");
   }
 });

答案 1 :(得分:0)

ASP.NET MVC中的FormCollection与输入元素的name属性相关联,将name属性添加到select HTML元素中,如下所示:< / p>

<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);

答案 2 :(得分:0)

我在代码中看到的唯一缺少的是下拉列表的名称属性。

   <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属性,而form collection正在使用name属性作为引用,这就是获取null值的原因。

与第二个示例相同,在参数

中引用DropDown name属性而不是ID
public ActionResult SetOptionForUser(int myDropDownName) //null
{
    string option = myDropDownName.ToString(); //null error
    return RedirectToAction("AnotherAction", "AnotherController");
}

答案 3 :(得分:0)

ASP.NET MVC中的FormCollection将转到输入元素的name属性

所以添加此属性 name =“ddlSelect”

答案 4 :(得分:0)

MattoMK,

请为您的模型发布代码。 通常,模型将包含运行webform所需的所有数据以及发回数据的帖子。在您的视图中,您应该选择“模型”字段。你似乎有Model.Persons,它可能是一个描述人的类的可枚举。

<强> MODEL

你没有描述你的模型,所以只显示一个假的模型,只有两个属性,一个用于保存列表选择的字符串和一个人员列表。希望您的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后数据的结构。

希望这有助于。