C# ASP.NET MVC:将复杂视图模型传递给控制器

C# ASP.NET MVC:将复杂视图模型传递给控制器,c#,asp.net-mvc,kendo-ui,model-binding,kendo-treeview,C#,Asp.net Mvc,Kendo Ui,Model Binding,Kendo Treeview,首先,我搜索了我的问题,但找不到任何有助于我进一步研究的东西 我正在尝试实现一个视图,该视图允许我为当前用户设置权限 作为数据结构,我使用以下递归类,其中每个PermissionTree对象引用子权限(权限在我的应用程序中是分层结构的): 在am中,使用如下强类型视图: @model PermissionTree //.... @using (Html.BeginForm("Permissions", "Permission", null, FormMethod.Post, new { @cl

首先,我搜索了我的问题,但找不到任何有助于我进一步研究的东西

我正在尝试实现一个视图,该视图允许我为当前用户设置权限

作为数据结构,我使用以下递归类,其中每个PermissionTree对象引用子权限(权限在我的应用程序中是分层结构的):

在am中,使用如下强类型视图:

@model PermissionTree
//....
 @using (Html.BeginForm("Permissions", "Permission", null, FormMethod.Post, new { @class = "stdform stdform2" }))
{    
<input name="save" title="save2" class="k-button" type="submit" />

<div class="treeview">
//i am using the telerik kendoUI treeview
    @(Html.Kendo().TreeView()
            .Name("Permissions")
            .Animation(true)
            .ExpandAll(true)
            .Checkboxes(checkboxes => checkboxes
                .CheckChildren(true)
            )
            .BindTo(Model, mapping => mapping
                .For<PermissionTree>(binding => binding
                .Children(c => c.Children)
                .ItemDataBound( (item, c) => {
                    item.Text = c.Node.PermissionName;
                    item.Checked = c.HasPermission;
                })

                )
            )
      )
@模型权限树
//....
@使用(Html.BeginForm(“Permissions”,“Permission”,null,FormMethod.Post,new{@class=“stdform stdform2”}))
{    
//我用的是telerik kendoUI treeview
@(Html.Kendo().TreeView())
.Name(“权限”)
.动画(真实)
.ExpandAll(正确)
.复选框(复选框=>复选框
.CheckChildren(true)
)
.BindTo(模型,映射=>映射
.For(绑定=>绑定
.儿童(c=>c.儿童)
.ItemDataBound((item,c)=>{
item.Text=c.Node.PermissionName;
item.Checked=c.HasPermission;
})
)
)
)
好的,当我单击按钮时,我希望我的viewmodel被发送到控制器操作,该操作由
[HttpPost]
修饰。但是当我调试应用程序时,收到的模型实际上并不包含我的数据(尽管它不是空的)。 有人知道我如何实现目标并获得整个viewmodel吗

致以最良好的祝愿,
r3try

我认为最好在这里使用JSON post,这样在javascript端准备对象就很容易了

我不知道你的HTML是什么样子,也不知道元素的名称,你可以轻松地使用javascript/Jquery构建客户端json对象,该对象具有类似的名称和更精简的层次结构/数据类型,就像在
PermissionTree
类中一样。然后使用Ajax post作为json发布

 var PermissionTree={Node:{},HasPermission:false,Children:{}}
 $.ajax({  data:PermissionTree
                            type: "POST",
                            url: 'YourController/Permissions',
                            contentType: "application/json; charset=utf-8",
                            dataType: "json",
                            success: function (result) {   
               }
);   

重要的是,您需要找到一种更好的方法来通过树状视图并用javascript构建对象。

因为我无法实现这一点,所以我尝试了一种稍微不同的方法:

添加节点的示例: -按add按钮->执行ajax调用->在nhibernate中添加节点->使用新数据(包括新节点)再次调用视图

ajax请求调用的控制器操作:

[Authorize]
    [HttpPost]
    public ActionResult AddPermission(string parentPermissionName, string permissionName)
    {
        var pd = ServiceContext.PermissionService.permissionDao;
        Permission parentPermission = pd.GetPermissionByName(parentPermissionName);
        if (parentPermission == null) {
            parentPermission = pd.GetRoot();
        }

        if (parentPermission != null && !string.IsNullOrEmpty(permissionName) && !pd.PermissionExists(permissionName))//only add with a name
        {
            pd.AddPermission(parentPermission, permissionName);
        }
        //refresh data
        PermissionTree permissionTree = LoadTreeSQLHierarchy(null, false);//start at root
        return View("Permissions", permissionTree);
    }
视图中的Ajax请求:

function addNode() {
    //... get the data here
    var addData = { parentPermissionName: selectedNodeName, permissionName: newNodeName };

    $.ajax(
       {
           data: addData,
           type: "POST",
           url: '@Url.Action("AddPermission", "Permission")',
           dataType: "json",
           success: function (result) {
               //$('.centercontent').html(response);//load to main div (?)
               return false;
           },
           error: function (xhr, ajaxOptions, thrownError) {
               alert(xhr.status + ":" + thrownError);
               return false;
           }
       }
    );
    return false;
}
但是当我执行此命令时,我会收到一个错误,指出json.parse命中了一个无效字符(我在ajax的error函数中的警报中得到了这个错误)。 从这条消息判断,问题是我返回的是html,但ajax调用需要json左右。。。
但是,用新数据重新加载视图的正确方法是什么?我能告诉ajax调用根本不要返回,只执行被调用的控制器方法吗?

视图中有输入字段吗?没有,我只使用带有checkboxesTry的树视图来查看模型绑定中发生的情况:@r3try好吧,那是你的问题。怎么了提交时,在您的操作方法中作为参数传递的仅是输入字段列表。您可以尝试添加
@Html.HiddenFor(z=>z.HasPermission)
在您的视图中,您将看到它将作为控制器中的参数传递。您真的需要从视图中获取它吗,
PermissionTree
对象是否在服务器端可用?问题是,我想让用户在树中选中/取消选中权限,我需要这些信息(最终的选择集)在我的控制器中保存数据。或者我是从一个完全错误的角度来完成这项任务的?我想我不完全理解这一点…你的意思是当我单击提交按钮时,我应该使用javascript手动创建序列化对象,然后使用ajax将数据发布到我的控制器?我真的不明白为什么会出现这种情况当您甚至无法将viewmodel传递回控制器时,在mvc中键入视图。这不是修改模型的视图点吗?..*叹气*别沮丧-谢谢您的回答!;)问题在于您拥有的模型集合。要发布强类型视图并填充模型,您需要在视图中使用正确的命名约定视图。我的意思是,在HTML中,您的输入应该有
Children[0]这样的名称。例如,Chilren[1]。权限
。如果您没有权限,最好的方法是填充JSON对象并使用Ajax传递它。我正在尝试执行您所说的自动模型绑定工作所必需的操作(命名约定)。我如何设置我的剑道树视图以满足此要求?我认为您可以在提交表单之前编写一些jquery以正确方式更新节点中的名称。
[Authorize]
    [HttpPost]
    public ActionResult AddPermission(string parentPermissionName, string permissionName)
    {
        var pd = ServiceContext.PermissionService.permissionDao;
        Permission parentPermission = pd.GetPermissionByName(parentPermissionName);
        if (parentPermission == null) {
            parentPermission = pd.GetRoot();
        }

        if (parentPermission != null && !string.IsNullOrEmpty(permissionName) && !pd.PermissionExists(permissionName))//only add with a name
        {
            pd.AddPermission(parentPermission, permissionName);
        }
        //refresh data
        PermissionTree permissionTree = LoadTreeSQLHierarchy(null, false);//start at root
        return View("Permissions", permissionTree);
    }
function addNode() {
    //... get the data here
    var addData = { parentPermissionName: selectedNodeName, permissionName: newNodeName };

    $.ajax(
       {
           data: addData,
           type: "POST",
           url: '@Url.Action("AddPermission", "Permission")',
           dataType: "json",
           success: function (result) {
               //$('.centercontent').html(response);//load to main div (?)
               return false;
           },
           error: function (xhr, ajaxOptions, thrownError) {
               alert(xhr.status + ":" + thrownError);
               return false;
           }
       }
    );
    return false;
}