【问题标题】:C# Razor View passing null object to JavaScriptC# Razor View 将 null 对象传递给 JavaScript
【发布时间】:2018-11-01 16:59:02
【问题描述】:

这里是纲要。用户既可以匿名也可以登录查看剃须刀页面。如果他们已登录,他们将获得某些功能。在我的控制器中,我有一个布尔值 isAnonymous,我将其设置为 true 或 false,具体取决于是否有登录用户。我将isAnonymous 传递给我的视图模型,该模型被发送到剃须刀页面。

在 razor 页面中,我有一个 javascript 脚本标记,它需要检索该布尔值,如果 isAnonymous 为 false(表示有人已登录),则启动对服务器的两个 ajax 调用之一。

我在脚本标记中做的第一件事是获取 isAnonymous 值并将其转换为 JavaScript 布尔值:

var isAnonymous = @Json.Encode(Model.IsAnonymous);

控制台记录后,这似乎正确返回。

然后我输入我的 if 语句。这里的总结是,如果用户没有登录,嵌套在 if 语句中的这些函数都不会触发,因为它们将 ApplicationUser 作为模型的一部分。如果没有登录用户,Model.User 为空并抛出Null Reference Exception。我认为将我的 ajax 调用放在 if 语句中可以防止异常,但逻辑似乎正在通过if (isAnonymous == false) 直接吹过,尽管有逻辑,但仍会触及这些函数。关于为什么会发生这种情况的任何想法?当isAnonymous 为真时,我无法触发函数。

if (isAnonymous == false) {
    if ($('.bookmark-btn').hasClass('bookmark-story-btn')) {
        addBookmark();
    } else {
        removeBookmark();
    }

    function addBookmark() {
    //bookmark a story btn click event
    $('.bookmark-story-btn').on('click', function () {

        var storyid;

        //the storyid should come as a string - 
        //try to parse it as an int for the controller
        if (!isNaN($(this).attr('storyid'))) {

            storyid = parseInt($(this).attr('storyid'))
            //verify successful conversion from string to int before ajax call
            if (typeof (storyid) == 'number') {
                var userid = $(this).attr('userId')

                var newBookmark = {
                                    UserId: userid,
                                    StoryId: storyid,
                                  };

                $.ajax({
                    url: "/api/bookmark/new",
                    method: "POST",
                    data: newBookmark,
                    success: function (data) {
                            //remove the save bookmark btn and dynamically add
                            //the remove bookmark btn so 
                            //the page doesn't require a refresh
                            $('.bookmark-story-btn').remove();
                            $('.bookmark-btn-group').append("<button bookmarkId='" 
                                + data.Id 
                                + "' userId=@Model.User.Id storyId=@Model.StoryId"
                                +" class='btn remove-bookmark-btn bookmark-btn'>"
                                +"<i class='fas fa-2x fa-bookmark'></i></button>")
                            removeBookmark();
                        },
                    error: function (error) {
                            $('.page-alert').css('visibility', 'visible')
                                .html("Whoops. Something went wrong."
                                        +" Adding the bookmark failed.")
                            //automatically close the alert-danger div 
                            //after 2 seconds
                            setTimeout(function () {
                                $('.page-alert').css('visibility', 'hidden')
                            }, 3000);
                        }
                    });
                }
            }
        });
    }

    function removeBookmark() {
        //remove a bookmark click event
        $('.remove-bookmark-btn').on('click', function () {

            if (!isNaN($(this).attr('bookmarkid'))) {
                bookmarkid = parseInt($(this).attr('bookmarkid'))
                //verify successful conversion from string to int before ajax call
                if (typeof (bookmarkid) == 'number') {

                    //call the ajax
                    $.ajax({
                        url: "/api/bookmark/" + bookmarkid,
                        method: "DELETE",
                        success: function (data) {
                            //show-hide the appropriate icons
                            $('.remove-bookmark-btn').remove();
                            $('.bookmark-btn-group').append("<button userId=@Model.User.Id"
                                +" storyId=@Model.StoryId class='btn bookmark-story-btn"
                                +" bookmark-btn'><i class='far fa-2x fa-bookmark'>"
                                +"</i></button>")
                            addBookmark();
                        },
                        error: function (error) {
                            $('.page-alert').css('visibility', 'visible')
                                    .html("Whoops. Something went wrong here."
                                        +" Removing the bookmark didn't work.")
                            //automatically close the alert-danger div 
                            //after 2 seconds
                            setTimeout(function () {
                                $('.page-alert').css('visibility', 'hidden')
                            }, 3000);
                        }
                    })
                }
            }
        })
    }
} 

【问题讨论】:

  • 只是一个想法,但是为什么要传递一个变量而不是在视图和服务器端都使用Request.IsAuthenticated,如果您依赖于变量集客户端(javascript),那么这可以通过用户,所以无论如何您都需要验证服务器端。看起来您也将 UserId 公开为客户端变量,因此任何人都可以在提交之前对其进行更改。
  • 尝试调试'if (isAnonymous == false) {'。它可能未定义或不是布尔值。
  • 谢谢@TomJohn。我会试试的。为了隐藏 userId,我应该把它放在 viewbag 中吗?即使我必须在我的 ajax 发布操作中发送它,你如何建议我从客户端隐藏它?
  • @TomJohn 没关系。我使用 Request.IsAuthenticated 完成了所有工作。谢谢!

标签: javascript c# asp.net-mvc razor


【解决方案1】:

您可以在 Razor 视图中使用Request.IsAuthenticated

@if(Request.IsAuthenticated)
{
    <script>
        ' your authenticated client side script here
    </script>
}

然后在您的控制器中发布时再次检查服务器端,例如:

    public ActionResult Index()
    {
        if(Request.IsAuthenticated)
        {
            //server logic here
        }
    }

如果你用AuthoriseAttribute 修饰方法,用户会得到一个 403 Unauthorized。

然后您可以为 UserId 执行类似的服务器端操作:

    [Authorize]
    public ActionResult Index()
    {
        var userId = User.Identity.Name;
    }

那么您甚至不需要传递 UserId。这一切都基于使用常见的身份实践:

https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity

【讨论】:

    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多