Chrome(仅限!)遇到带有重定向的NullReferenceException

时间:2017-04-27 18:26:31

标签: asp.net asp.net-mvc asp.net-mvc-5

好的,前面这里:这在其他所有浏览器中100%有效。但Chrome(特别是其变体,如Vivaldi和Blisk)在重定向被触及后被NullReferenceException抛出时失败了。威士忌探戈狐步。

当前项目:

  • DotNet 4.6.2
  • MVC 5
  • ASP.NET MVC 5 HTML5 Boilerplate

我通过控制器填写几个列表:

public static class SelectLists {
  public static IEnumerable<SelectListItem> ProvinceList() {
    return new List<SelectListItem> {
      new SelectListItem() {Text = @"British Columbia", Value = "2"},
      new SelectListItem() {Text = @"Alberta", Value = "1"},
      new SelectListItem() {Text = @"Saskatchewan", Value = "5"},
      new SelectListItem() {Text = @"Manitoba", Value = "3"},
      new SelectListItem() {Text = @"Ontario", Value = "4"}
    };
  }
  public static IEnumerable<SelectListItem> ClientList() {
    return new List<SelectListItem> {
      new SelectListItem() {Text = @"ClientType1", Value = "1"},
      new SelectListItem() {Text = @"ClientType2", Value = "2"},
    };
  }
}

然后我通过模型将它们拉进去:

[Validator(typeof(IndexValidator))]
public class IndexViewModel {
  public int Province { get; set; }
  public int Client { get; set; }

  public IEnumerable<SelectListItem> ProvinceList => SelectLists.ProvinceList();
  public IEnumerable<SelectListItem> ClientList => SelectLists.ClientList();
}

然后将模型转储到View:

@using(Html.BeginForm("Process", "Home", FormMethod.Post, new { @class = "form-inline body-form", role = "form" })) {
  @Html.AntiForgeryToken()
  @Html.DropDownListFor(x => x.Province, Model.ProvinceList, "« ‹ Select › »", new { @class = "form-control required" })<br />
  @Html.ValidationMessageFor(x => x.Province)<br />
  foreach(var item in Model.ClientList) {
    @Html.RadioButton("Client", item.Value, new {id = item.Text}) <label for="@item.Text">@item.Text</label><br />
  }
  @Html.ValidationMessageFor(x => x.Client)<br />
  <button type="submit" class="btn btn-primary btn-lg">Submit</button>
}

提交后,表单已经过验证:

public class IndexValidator : AbstractValidator<IndexViewModel> {
  public IndexValidator() {
    RuleFor(x => x.Province).NotEmpty().WithMessage("You must choose your province.");
    RuleFor(x => x.Client).NotEmpty().WithMessage("Are you [client type 1] or [client type 2]?");
  }
}

然后我处理它们:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Process(IndexViewModel model) {
  if (ModelState.IsValid) {
    switch(model.Client) {
      case 1:
        return Redirect("https://example1.com");
      default:
        return Redirect("https://example2.com");
    }
  }
  return View("Index", model);
}

所以真正奇怪的是,当我逐步使用调试器时,一切都与每个浏览器相同,甚至调试器都会点击Process()方法的结束标记。同样,调试器会清楚地显示正确的重定向,表明switch有内容可以对其进行操作。

但是一旦该方法完全处理完毕,Chrome(特别是其变体,如Vivaldi和Blisk)会在代码中导致NullReferenceException,从而阻止重定向重定向。完全清楚:一旦调试器到达方法的结束括号,下一步(F11)就是NullReferenceException 没有其他浏览器

使用其他类型的重定向,例如

return new RedirectResult("https://example.com/", false);

引发同样的问题。

我完全不知道Chrome是如何能够自行触发这样的错误的。

更新

用以下三元替换switch

return Redirect(model.Client == 1 ? "https://example1.com/" : "https://example2.com/");

没有区别 - Chrome在退出方法时仍会抛出NullReferenceException。所有其他浏览器都可以正常处理重定向。

更新2:

嗯...完整的披露包括我现在提到我正在使用ASP.NET MVC HTML5 Boilerplate。此模板还附带了一个名为内容安全策略的小宝石。虽然它应该增加安全性,但它也增加了通过监视器的挫败感。

在这种情况下,在Chrome(以及为什么只有Chrome?)下,CSP会阻止外向重定向工作。如同,它会抛出NullReferenceException

为什么要传出重定向?为什么只在Chrome上?谁知道f ** k。特别是因为它是特定于Chrome的,并且不会影响任何其他浏览器。现在我完全关闭了CSP,Chrome现在可以使用重定向。

0 个答案:

没有答案