Question

firs of all i searched for my question but couldnt find anything that helped me get any further.

i am trying to implement a view which allows me to set permissions for the current user.

As the data-structure i use following recursive class where each PermissionTree-Object references the sub-permissions (permissions are hierarchically structured in my application) :

public class PermissionTree
{
        public Permission Node; //the permission object contains a field of type SqlHierarchyId if that is relevant
        public bool HasPermission;
        public IList<PermissionTree> Children;
   //i cut out the constructors to keep it short ...
}

here is how the controller looks like:

//this is called to open the view
 public ActionResult Permissions()
    {
        //pass the root element which contains all permission elements as children (recursion)
        PermissionTree permissionTree = PopulateTree();//the fully populated permission-tree
        return View(permissionTree);
    }

//this is called when i submit the form
    [HttpPost]
    public ActionResult Permissions(PermissionTree model)
    {
        SetPermissions(model);
        ViewData["PermissionsSaved"] = true;

        return View(model);//return RedirectToAction("Index");
    }

in am using a strongly typed view like this:

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

                )
            )
      )

ok, so when i click the button, i want my viewmodel to be sent to the controller action that is decorated with [HttpPost]. But when i debug the application, the received model does not really contain my data (it is not null though). Does anyone know how i can achieve my goal and get the whole viewmodel?

best regards, r3try

Was it helpful?

Solution

I think it's better to use a JSON post here ,then it's easy to prepare the object in the javascript side.

I don't know how your HTML looks like or the names of the elements you can easyly use javascript/Jquery to build the client side json object with similar names and slimier hierarchy/dataTypes just like in the PermissionTree class. And then use Ajax post to post as 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) {   
               }
);   

The important thing is you need to find a better way of going throuth the tree view and build the object in javascript.

OTHER TIPS

as i cant get that to work i was trying a slightly different approach:

example for adding a node: - press add button -> execute ajax call -> add the node in nhibernate -> call the view again with the new data (the new node included)

controller-action that is called by the ajax request:

[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 Request in the View:

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

But when i execute this i get an error stating that json.parse hit an invalid character (i get this error at the alert in the ajax's error function). Judging from that message i would say that the problem is that i am returning html but the ajax call expects json or so... But what is the correct way to just reload my view with the new data? Can i somehow tell the ajax call to not go back at all and just execute the called controller-method?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top