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

问题描述 投票:0回答:6

我是 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
6个回答
2
投票

普通表单提交

如果您的 select 元素名称和您的 http post 操作方法参数名称相同,您的正常表单提交应该可以工作。

<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.DropDownListFor
Html.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!");
   }
 });

0
投票

我发现您的代码中唯一缺少的是下拉列表的 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");
}

0
投票

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

0
投票

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

因此添加此属性name =“ddlSelect”


0
投票

马托MK,

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

型号

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

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 上构建。

希望这有帮助。


0
投票

我的问题是第一个选项被禁用,因此将选择发送为空或表单键中不存在。 刚刚从第一个选项中删除了禁用,成功了。

  <option selected="selected" disabled value="">Agent</option>

替换为:

 <option selected="selected" value="">Agent</option>

 <select id="agent_id" name="agent"  class="form-control">
      <option selected="selected" disabled value="">Agent</option>
      @{
          foreach (var agent in agents)
          {
              <option value="@agent">@agent</option>
          }
      }
  </select>
© www.soinside.com 2019 - 2024. All rights reserved.