2

我正在使用 Kendo Scheduler,用户可以在我的本地数据库中创建、删除、更新、编辑事件。但是我在这个 webapp 上与不同的用户合作,所以我只希望这些用户能够编辑、删除和更新他们个人创建的事件。所以用户 1 可以删除用户 1 创建的事件,但不能删除用户 2 或 3 等创建的事件...

我以为我只是修改模型/控制器以检查登录用户的用户 ID 与事件数据库中的用户 ID。

public virtual JsonResult Meetings_Destroy([DataSourceRequest] DataSourceRequest request, MeetingViewModel meeting)
{
    var userid = System.Convert.ToInt32(Session["userID"]);

    if (ModelState.IsValid)
        {
            if (meeting.UserID== userid)
            {
                meetingService.Delete(meeting, ModelState);
            }
            else
            {
                "cant delete"
            }
        }

    return Json(new[] { meeting });
}

但这似乎不起作用,当单击删除事件消失但重新加载后,您会看到它实际上并没有真正从数据库中删除......这当然不是一个好的解决方案,因为目标当然是该用户无法删除该事件。

有任何想法吗?


看法

$(function () {
    $("#scheduler").kendoScheduler({
        date: new Date(Date.now()),
        startTime: new Date(2013, 5, 13, 9, 0, 0, 0),
        height: 800,
        timezone: "Etc/UTC",
        dataSource: {
            transport: {
                read: {
                    url: "@Url.Action("Meetings_Read", "Home")",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                update: {
                    url: "@Url.Action("Meetings_Update", "Home")",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                create: {
                    url: "@Url.Action("Meetings_Create", "Home")",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                destroy: {
                    url: "@Url.Action("Meetings_Destroy", "Home")",
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                parameterMap: function (options, operation) {
                    if (operation === "read") {
                        var scheduler = $("#scheduler").data("kendoScheduler");
                        var result = {
                            start: scheduler.view().startDate(),
                            end: scheduler.view().endDate()
                        }
                        return kendo.stringify(result);
                    }
                    return kendo.stringify(options);
                }
            },
            error: error_handler,
                schema: {
                    model: {
                        id: "MeetingID",
                        fields: {
                            MeetingID: { type: "number" },
                            title: { from: "Title", type: "string", defaultValue: "No title", validation: { required: true } },
                            description: { from: "Description", type: "string" },
                            start: { from: "Start", type: "date" },
                            startTimezone: { from: "StartTimezone", type: "string" },
                            end: { from: "End", type: "date" },
                            endTimezone: { from: "EndTimezone", type: "string" },
                            recurrenceRule: { from: "RecurrenceRule", type: "string" },
                            recurrenceId: { from: "RecurrenceID", type: "number", defaultValue: null },
                            recurrenceException: { from: "RecurrenceException", type: "string" },
                            isAllDay: { from: "IsAllDay", type: "boolean" },
                            Timezone: { type: "string" },
                            RoomID: { type: "number", defaultValue: null },
                            Attendees: { type: "object" }
                        }
                    }
                }

            },

        });
    });

JAVASCRIPT

<script type="text/javascript">
    function error_handler(e) {
        if (e.errors) {
            var scheduler = $("#scheduler").data("kendoScheduler");
            scheduler.one("dataBinding", function (e) {
                e.preventDefault();
                for (var error in e.errors) {
                    alert("can't delete")
                }
            })
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
        }
    }

控制器

   public virtual JsonResult Meetings_Destroy([DataSourceRequest] DataSourceRequest request, MeetingViewModel meeting)
    {
            if (ModelState.IsValid)
            {
                if(meeting.UserID == System.Convert.ToInt32(Session["userID"]))
                {
                meetingService.Delete(meeting, ModelState);
                }
                else
                {
                ModelState.AddModelError("","cant delete");
                }
            }

        return Json(new[] { meeting });
    }
4

4 回答 4

3

我的项目也有类似的情况,我的用户在日历上做事的权限有限。我发现您必须防止用户不应该做的添加、编辑和删除之类的事情,您可以使用 JavaScript 事件来做到这一点。然后,在 JavaScript 函数中,如果满足(或不满足)条件,则调用 e.preventDefault(); 方法。 这是客户端事件的演示

查看(HTML 5 片段)

remove: RemoveMe,
edit: EditMe,
add: AddMe,

查看(MVC 版本片段)

.Events(events =>
{
    events.Add("AddMe").Edit("EditMe").Remove("RemoveMe");
})

JavaScript

function AddMe (e) {
    if (SomeValue != SomeOtherValue) 
       e.preventDefault();
};

function EditMe (e) {
    if (SomeValue != SomeOtherValue) 
       e.preventDefault();
};

function RemoveMe (e) {
    if (SomeValue != SomeOtherValue) 
       e.preventDefault();
};

所以,好消息是这会阻止日历显示更新(无论是否发生删除),但它不会阻止删除提示(又名。“您确定要删除此事件吗?”)。防止客户端上的操作是要走的路,您可以将警报或通知扩展到屏幕(因为无论如何您都会在 JavaScript 函数中遇到条件),所有这些都是为了通知用户他们不能做某事。

于 2014-05-27T19:56:24.647 回答
1

ModelState.AddModelError("cant delete"); return Json(ModelState.ToDataSourceResult());

在视图中

.Read("Grouping_Horizontal_Read", "Scheduler")
        .Create("Grouping_Horizontal_Create", "Scheduler")
        .Destroy("Grouping_Horizontal_Destroy", "Scheduler")
        .Update("Grouping_Horizontal_Update", "Scheduler")
        .Events(events => events.Error("error"))

.Events(events => events.Error("error")) 是诀窍,现在对错误的功能很重要

function error(args) {
    if (args.errors) {

        var scheduler = $("#scheduler").data("kendoScheduler");
        scheduler.one("dataBinding", function (e) {
            e.preventDefault();   // cancel scheduler rebind if error occurs

            for (var error in args.errors) {

                alert(error + " args: " + args.errors[error].errors[0])

            }
        });
        args.sender.cancelChanges();
    }
}
于 2014-05-27T12:58:53.900 回答
0

这也取决于您如何创建会议。

因为要删除任务,您只需要一个唯一的 ID。

现在它只是在 JSON 中被删除,而不是在后端数据库中,因为我猜 meeting.id 与触发 create 事件时生成的 taskID 不匹配。

当在调度程序中创建任务时,我建议将 taskID 保存在 ViewBag、SQL 表或其他地方。然后在触发 remove 事件时将此 id 作为参数传递给您的 Meetings_Destroy 方法。

并且 [如上一个答案所述] 使用 JavaScript 删除事件来验证登录用户,因为 e.preventDefault() 可用于限制在不满足条件时触发 Meetings_Destroy 方法。如果在控制器方法 [Meetings_Destroy] 处进行了调试,它将从调度程序中删除事件[在数据库中是否成功删除],即从前端,但会在页面刷新时将其带回。

于 2014-12-03T11:00:22.870 回答
0

我也有同样的情况。我采取了不同的方法来解决它。在编辑功能中,我比较了任务 ID 和当前用户 ID,然后我只是隐藏了那些按钮保存、取消和删除。这些按钮将只有创建该按钮的用户。

function(e) 
{
    var customHide13= $(".k-scheduler-update, .k-scheduler-delete, .k-scheduler-cancel");

    if (taskId == userId)
        customHide13.show();
    else
        customHide13.hide();
},
于 2014-12-10T10:52:55.833 回答