解析复选框将值更改为模型,然后在 VIEW ASP.Net MVC 中单击按钮时将其更改为 JSON 对象

Parse checkbox change value to Model and then to JSON object on button click in VIEW ASP.Net MVC

使用表单,用户应该能够取消选中预先选择的 checkbox 并将该状态保存在 AJAX post 上,通过 JSON 对象保存到 ControllerASP.Net MVC

要求:

  1. 取消选中预选复选框应该将数据库 属性 中的一行从 "Active" = 'Y' 更改为 "Active=" = 'N'
  2. 新选中的复选框将在数据库中创建一个完整的新行

问题:

  1. 取消选中所选文本框后,模型未在 VIEW 中更新。因此服务器端数据不会更新。在将数据解析为 AJAX 调用之前需要客户端更新。
  2. 不知道如何捕获复选框值的变化并将其传递给模型,以便解析后的数据可以更改为按钮 click/submit 形式。
  3. 以下代码也会给出错误 200,因为数据类型在提交时可能不正确(在此处执行按钮提交)。

查看:

@model List<DashboardPermissionTool.ViewModels.UserViewModel>
@using (@Html.BeginForm(new { id = "UserForm" }))
{
<table class="table">
    <tr>
        <th>User</th>
        @for (int i = 0; i < Model[0].Roles.Count; i++)
        {
            <th>
                @Model[0].Roles[i].RoleName
            </th>
        }
    </tr>
    @for (int i = 0; i < Model.Count; i++)
    {
        <tr>
            <td>
                @Html.HiddenFor(m => m[i].UserName)
                @Model[i].UserName
            </td>
            @for (int j = 0; j < Model[i].Roles.Count; j++)
            {
                <td>
                    @Html.CheckBoxFor(m => m[i].Roles[j].IsSelected)
                </td>
            }
        </tr>
    }
</table>

<div class="form-actions">
    <a id="SubmitUserRoles" class="btn btn-success submit" value="Save">Save changes</a>
</div>

<script>

    var parsedData = @Html.Raw( new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));

    $(document).ready(function() {
        $("#SubmitUserRoles").click(function () {

            $('input[type=checkbox]').on("change",function(){
                if($(this).prop('checked'))
                {
                    $(this).attr('checked', false); 
                }
                else
                {
                    $(this).attr('checked', true); 
                }                  
            });

              $.ajax({
                url: '@Url.Action("Create", "User")',
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                cache: false,
                dataType: 'json',
                data: JSON.stringify(parsedData),
                success: function (data) {
                    console.log(data);
                }, error: function (xhr, ajaxOptions, error) {
                    alert(xhr.status);
                    alert("Error: " + xhr.responseText);
                }
            });
        });
    });
</script>

}

HTML响应::对于每个选中的复选框响应如下:

<td>
     <input checked="checked" data-val="true" data-val-required="The IsSelected field is required." name="[0].Roles[0].IsSelected" type="checkbox" value="true" />
     <input name="[0].Roles[0].IsSelected" type="hidden" value="false" />
</td>

对于每个未选中的复选框响应如下:

<td>
    <input data-val="true" data-val-required="The IsSelected field is required." name="[0].Roles[1].IsSelected" type="checkbox" value="true" />
    <input name="[0].Roles[1].IsSelected" type="hidden" value="false" />
</td>

视图模型:

public class UserViewModel
{
    public string UserName { get; set; }
    public List<RoleViewModel> Roles { get; set; }
}

public class RoleViewModel
{
    public string RoleName { get; set; } 
    public bool IsSelected { get; set; } 
}

控制器:

[HttpPost]
    public ActionResult Create(List<UserViewModel> model)
    {

        for (int i = 0; i < model.Count; i++)
        {
            for (int j = 0; j < model[i].Roles.Count; j++)
            {
                db.User.Add(new User
                {
                    username = model[i].UserName,
                    role = model[i].Roles[j].RoleName
                });                  
            }

            db.SaveChanges();
            return RedirectToAction("Index", "User");
        }
        return View("Index", model);
    }

您的代码存在多个问题。

从控制器方法开始,在外部 for 循环中有一个 return 语句,这意味着您只保存第一个 UserViewModel 的值,然后退出方法。要保存所有记录,需要

[HttpPost]
public ActionResult Create(List<UserViewModel> model)
{
    for (int i = 0; i < model.Count; i++)
    {
        for (int j = 0; j < model[i].Roles.Count; j++)
        {
            db.User.Add(new User { username = model[i].UserName, role = model[i].Roles[j].RoleName });                  
        }
    }
    db.SaveChanges();
    return RedirectToAction("Index", "User");
}

但是从这个方法可以看出,你想在保存记录后重定向到Index()方法,所以使用ajax提交数据是没有意义的(ajax调用留在同一个页面上,不要重定向)所以你应该使用一个普通的提交按钮来提交表单(并删除你所有的脚本)。你需要改变

<a id="SubmitUserRoles" class="btn btn-success submit" value="Save">Save changes</a>

<input type="submit" class="btn btn-success submit" value="Save" />

还要注意 value 不是 <a> 元素的有效属性。

但是为了解决您的代码的其他问题,我们假设您确实希望停留在同一页面上并更新 DOM。

第一个

var parsedData = @Html.Raw( new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));

(您可以简单地使用 var parsedData = @Html.Raw(Json.Encode(Model)) 来代替)正在序列化原始模型,因此您只需回发原始值,而不是编辑后的值。为了传递编辑后的值,您 ajax 选项需要

data: $('form').serialize(),

下一个

contentType: 'application/json; charset=utf-8',

表示您将数据发送为json,但您没有对数据进行字符串化。需要

data: JSON.stringify($('form').serialize()),

为了绑定,但这是不必要的,你只需要删除 contentType 选项,以便它使用默认的 'application/x-www-form-urlencoded; charset=UTF-8'

下一个

dataType: 'json',

表示您指定方法 return json,但实际上它是 returning html,因此它会抛出异常。它需要是 dataType: 'html', 或简单地删除该选项,ajax 方法将解决它。

您还需要删除 $("#SubmitUserRoles").click(function () { ... } 脚本。 checked 属性的存在意味着它被选中,而 checked="checked"checked="true"check="false"checked="anything" 都意味着完全相同的事情 - 复选框被选中。幸运的是,该代码永远不会执行(如果执行,它会搞砸一切),因为您只在 $("#SubmitUserRoles").click(function () { 的处理程序中添加处理程序,这会引发异常。

终于

@using (@Html.BeginForm(new { id = "UserForm" }))

正在为 id 添加路由值(如果您查看生成的 html,您将看到 action="../Create/UserForm"(或 action="../Create?id=UserForm",具体取决于您的路由(并且您的方法没有参数 string id)。我假设您认为它向 <form> 标记添加了一个 id 属性,在这种情况下您需要使用 [=46] 之一=] 的 BeginForm() 接受 htmlAttributes。但是,只需要添加一个 id 属性以与 css 或 javascript 选择器一起使用,这样您就可以使用

@using (@Html.BeginForm())