0

使用一个表单,用户应该能够取消选中预选checkbox并将该状态保存在AJAXpost through JSONobject 到ControllerinASP.Net MVC

在此处输入图像描述

要求:

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

问题:

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

看法:

@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);
    }
4

1 回答 1

1

您的代码存在多个问题。

从控制器方法开始,您return在外for循环中有一条语句,这意味着您只保存第一个的值,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',

意味着您指定该方法返回 json,但实际上它正在返回 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)。我假设您认为它为标签添加了一个id属性,其中<form>如果您需要使用该 accept的重载之一. 但是, 它只需要添加一个用于 css 或 javascript 选择器的属性, 所以你可以使用BeginForm()htmlAttributesid

@using (@Html.BeginForm())
于 2016-10-24T23:49:58.553 回答