如何在服务器端Blazor中通过HttpContext注销

时间:2019-07-29 08:22:07

标签: asp.net-core blazor blazor-server-side

我在Blazor服务器端视图中访问HttpContext,以手动注销。我将此行添加到Startup.cs:services.AddHttpContextAccessor();中,并使用@inject IHttpContextAccessor HttpContextAccessor将其插入视图中。 我有一个尝试执行此代码的注销按钮:

await HttpContextAccessor.HttpContext.SignOutAsync("Cookies");

但是我收到以下错误消息:

System.InvalidOperationException: 'Headers are read-only, response has already started.'

如何防止此错误?

3 个答案:

答案 0 :(得分:3)

这也使我感到震惊,但是您需要注销功能位于Razor Page(不是Blazor组件)上。创建一个注销页面,并将您的注销代码放入OnGetAsync()方法中。

您的注销按钮然后可以链接到注销页面。

http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/4316/A-Demonstration-of-Simple-Server-side-Blazor-Cookie-Authentication.aspx-这是一个有用的示例

答案 1 :(得分:2)

如果您在通过模板创建项目时搭建了 Identity 并覆盖了旧的“LogOut.cshtml”,则“注销”按钮不会注销。假设您使用了默认的 IdentityUser 模型。我遇到了这个问题,如果其他人也有这个问题,我只想添加这个。我将 Blazor Server 与 .Net 5.0.3 的模板一起使用。您也可以删除 Logout.cshtml.cs 之后。

替换这个\Areas\Identity\Pages\Account\LogOut.cshtml

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater layoutInflater = (LayoutInflater) this.context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = layoutInflater.inflate(R.layout.list_item_service, null);
    }
    TextView txt_address_description = convertView.findViewById(R.id.txt_address_description);
    TextView txt_telephones = convertView.findViewById(R.id.txt_telephones);
    TextView txt_hours_description = convertView.findViewById(R.id.txt_hours_description);
    txt_address_description.setText((CharSequence) getChild(groupPosition, childPosition).getServiceAddress());
    txt_telephones.setText((CharSequence) getChild(groupPosition, childPosition).getContactDetails());
    txt_hours_description.setText((CharSequence) getChild(groupPosition, childPosition).getOpenHours());
    
    return convertView;
}

替换为

@page
@model LogoutModel
@{
    ViewData["Title"] = "Log out";
}

<header>
    <h1>@ViewData["Title"]</h1>
    @{
        if (User.Identity.IsAuthenticated)
        {
            <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
                <button type="submit" class="nav-link btn btn-link text-dark">Click here to Logout</button>
            </form>
        }
        else
        {
            <p>You have successfully logged out of the application.</p>
        }
    }
</header>

答案 2 :(得分:1)

不要使用IHttpContextAccessor。

我猜您正在使用 ASP.NET Core Blazor身份验证和授权新系统。如果没有,请立即开始。生命太短了,不能浪费在其他事情上。这是迄今为止为Blazor的身份验证和授权而创建的最好的产品,它基于Identity UI(当然,这不是Blazor)。此外,还有几个组件可用于控制应用程序中的身份验证和授权流程,例如在布局中显示“登录”按钮和“注销”按钮,可根据身份验证状态进行交替更改等

请转到此页面,开始学习这个出色的系统,然后针对您遇到的特定问题来到这里: https://docs.microsoft.com/en-us/aspnet/core/security/blazor/?view=aspnetcore-3.0&tabs=visual-studio

希望这对您有帮助...