Blazor Server中ASP.NET Identity注册POST请求获取URL参数问题
解决ASP.NET Identity注册页面Post时获取URL参数的问题
因为OnPostAsync处理的是POST请求,而URL中的查询参数不会自动绑定到POST方法的参数上(GET请求的参数仅在GET阶段生效),你可以通过以下两种可靠方式解决:
方案1:通过隐藏表单字段传递参数(推荐)
这个方法将URL参数存入页面模型,再通过表单的隐藏字段提交到POST方法,是最符合表单提交规范的方式:
- 确保
RegisterModel中存在公共属性Following(你已在OnGetAsync中赋值,只需保证属性公开可绑定):
public class RegisterModel : PageModel { // 其他已有代码... public string Following { get; set; } public string ReturnUrl { get; set; } public IList<AuthenticationScheme> ExternalLogins { get; set; } public async Task OnGetAsync(string returnUrl = null, string following = null) { ReturnUrl = returnUrl; Following = following; // 把URL参数存入模型属性 ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); } }
- 在
Register.cshtml的表单内部添加隐藏字段,将模型的Following值绑定到表单:
<form asp-route-returnUrl="@Model.ReturnUrl" method="post"> <!-- 其他表单元素(用户名、密码等)... --> <input type="hidden" asp-for="Following" /> <!-- 注册按钮等... --> </form>
- 修改
OnPostAsync,直接使用模型的Following属性(无需再声明参数):
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { // 在这里直接使用 this.Following 即可获取到传递的参数 // 执行你的注册逻辑,比如关联follow关系等 // ... if (result.Succeeded) { // 注册成功后的逻辑... return LocalRedirect(returnUrl); } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } // 注册失败时重新加载外部登录列表 ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); return Page(); }
方案2:通过TempData临时存储参数
如果不想修改表单,可以用TempData在Get阶段存储参数,Post阶段读取,但注意TempData是一次性的(读取后会被清除),如果注册失败需要返回页面,需要重新存入:
- 修改
OnGetAsync,将参数存入TempData:
public async Task OnGetAsync(string returnUrl = null, string following = null) { ReturnUrl = returnUrl; TempData["Following"] = following; // 存入TempData ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); }
- 在
OnPostAsync中读取TempData的值,若注册失败则重新存入:
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { var following = TempData["Following"] as string; returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { // 使用following参数执行注册逻辑 // ... if (result.Succeeded) { return LocalRedirect(returnUrl); } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } // 注册失败时,重新把参数存入TempData,避免页面返回后丢失 TempData["Following"] = following; ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); return Page(); }
为什么原来的方法不行?
GET请求的查询参数只会自动绑定到OnGetAsync的参数,POST请求是提交表单数据,默认只会绑定表单内的字段,不会自动读取URL上的查询参数,所以需要手动把参数传递到POST上下文里。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

