How to resolve issues with CRUD Operations in an A

2019-05-28 12:23发布

问题:

I've been trying to get the Kendo UI grid to act as a user management tool in a system I'm currently writing. I've bound data to the grid, using ASP.NET Identity to get the user information, but I can't seem to get the update or delete actions to fire on the grid.

I've set the grid up as below:

    @(Html.Kendo().Grid<MyProject.Models.UserInfo>()
    .Name("userGrid")
    .Columns(columns =>
    {
        columns.Bound(p => p.UserName);
        columns.Bound(p => p.FirstName);
        columns.Bound(p => p.LastName);
        columns.Bound(p => p.Region);
        columns.Bound(p => p.Roles);
        columns.Command(command => { command.Edit(); command.Destroy(); command.Custom("ViewDetails").Click("showDetails"); });
    })
    .Filterable()
    .Sortable()
    .Navigatable()
    .Resizable(r => r.Columns(true))
    .Editable(editable => { editable.Mode(GridEditMode.InLine); editable.DisplayDeleteConfirmation("Are you sure you want to delete this user?"); })
    .HtmlAttributes(new { style = "min-height:90px;max-height:450px;" })
    .DataSource(dataSource => dataSource
        .Ajax() 
        .Model(model =>
        {
            model.Id(p => p.UserId);
            model.Field(p => p.UserId).Editable(false);
            model.Field(p => p.FirstName).Editable(true);
            model.Field(p => p.LastName).Editable(true);
            model.Field(p => p.UserName).Editable(true);
            model.Field(p => p.Roles).Editable(false);
            model.Field(p => p.Region).Editable(false);
        }
        ).Read(read => read.Action("GetAllUsers", "Admin"))
        .Update(update => update.Action("UpdateUser", "Admin"))
        .Destroy(update => update.Action("DeleteUser", "Admin"))
    )
)

Where my model is defined as:

public class UserInfo
{
    public string UserId {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
    public string UserName {get;set;}
    public string Roles {get;set;}
    public string Region {get;set;}
}

And my AdminController contains the following methods:

        [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult GetAllUsers([DataSourceRequest]DataSourceRequest request)
    {
        using (var context = new ApplicationDbContext())
        {
            var users = context.Users.ToList();
            var moreUsers = users.Select(x => new UserInfo { UserName = x.UserName, UserId = x.Id, FirstName = x.FirstName, LastName = x.LastName, Region = x.RegionId.ToString(), Roles = string.Join(", ", x.Roles.Select(p => p.Role.Name).ToList()) }).ToList();
            return Json(moreUsers.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
        }
    }

    [AcceptVerbs(HttpVerbs.Post)]        
    public ActionResult UpdateUser([DataSourceRequest] DataSourceRequest request, UserInfo user)
    {
        if (user != null && ModelState.IsValid)
        {
            //userService.Update(user);
        }

        return Json(new[] { user }.ToDataSourceResult(request, ModelState));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteUser([DataSourceRequest] DataSourceRequest request, UserInfo user)
    {
        if (user != null && ModelState.IsValid)
        {
            //userService.Update(user);
        }

        return Json(new[] { user }.ToDataSourceResult(request, ModelState));
    }

Currently, when I click the "Delete" button, I receive a 404 not found error and the action performed by the grid is a GET in the format : localhost/MyProject/Admin/DeleteUser?UserId=x,FirstName=y... etc. I can't for the life of me work out why this is happening as I think I've followed the example set out in the demos pretty accurately.

Has anyone got any help for me?

回答1:

try to change this one on your view

.Read(read => read.Action("GetAllUsers", "Admin"))
.Update(update => update.Action("UpdateUser", "Admin"))
.Destroy(update => update.Action("DeleteUser", "Admin"))

to this one

.Read("GetAllUsers", "Admin")
.Update("UpdateUser", "Admin")
.Destroy("DeleteUser", "Admin")

and on your controller

public ActionResult UpdateUser([DataSourceRequest] DataSourceRequest request, UserInfo user) ...
public ActionResult DeleteUser([DataSourceRequest] DataSourceRequest request, UserInfo user) ...

to this one

public ActionResult UpdateUser([Bind(Prefix = "models")]IEnumerable<UserInfo> updatedItems)
{
foreach (var updatedItem in updatedItems.AsNotNull())
            {
                   //--your code---//
            }
}

public ActionResult DeleteUser([Bind(Prefix = "models")]IEnumerable<UserInfo> deletedItems)
{
foreach (var deletedItem in deletedItems.AsNotNull())
            {
                   //--your code---//
            }
}


回答2:

The order of the Kendo javascript files are important for this to work properly.

Make sure that this reference is that last one that loads, after the other kendo scripts.

  <script src="/Scripts/kendo.aspnetmvc.min.js"></script>

Please see here for further information:

http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/troubleshooting



回答3:

The issue was related to the fact the grid was performing a GET and not a POST, but unfortunately the solution provided by hutchonoid didn't work. That changed all the grid actions to posts, including the GET action. However, it did get me looking in the right place for the solution.

An answer given to another question actually resolved the issue. To get my grid working, I explicitly defined what action the grid actions should be:

.Read(read => read.Action("GetAllUsers", "Admin").Type(HttpVerbs.Get))
.Update(update => update.Action("UpdateUser", "Admin").Type(HttpVerbs.Post))
.Destroy(update => update.Action("DeleteUser", "Admin").Type(HttpVerbs.Post))

I'm still not entirely sure why the Telerik demo works without defining the type of the action, but I'm guessing it is related to the scripts. Perhaps the version of jQuery I'm using?