解决错误 - “返回 404 时已添加具有相同键的项目”
Posted
技术标签:
【中文标题】解决错误 - “返回 404 时已添加具有相同键的项目”【英文标题】:Solving Error - "An item with the same key has already been added when returning 404" 【发布时间】:2017-06-29 17:31:29 【问题描述】:我的自定义错误页面处理程序定义如下:
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
else
app.UseExceptionHandler("/Error");
app.UseStatusCodePagesWithReExecute("/Error/0");
app.UseMvc(routes =>
...
然后在错误控制器中:
public class ErrorController : Controller
public IActionResult Index(int errorCode)
switch (errorCode)
case 404:
return View($"~/Views/Error/errorCode.cshtml");
return View(errorCode);
在生产模式下一切正常,但在开发模式下,有两种情况:
-
我正在点击“就像那样”的 404 页面,它显示了我的自定义 404 页面(这是正确的)
我正在强制执行 404,例如。
if(nothingFound)
return NotFound();
然后它进入 ErrorController 操作,甚至是视图(404.cshtml),但之后它会打印整个调试标题:
ArgumentException:已添加具有相同键的项目。 键:System.Object
使用app.UseDeveloperExceptionPage()
时是否正常,还是我配置错误?
更新
堆栈跟踪:
System.ArgumentException: An item with the same key has already been added. Key: System.Object
at System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(Object key)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.<>c__DisplayClass6_0.<<UseStatusCodePagesWithReExecute>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Web.BrowserLink.Runtime.BrowserLinkMiddleware.<ExecuteWithFilter>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
【问题讨论】:
你是说异常消息显示在开发服务器而不是到达 ErrorController ? 请发布该异常的堆栈跟踪。 @Kira 是的,但只有当我使用某些功能强制错误时,例如。未找到()。当访问不存在的路线时,它适用于生产和开发。我完全可以在开发模式下请求没有到达错误控制器,但我希望除了这个异常之外还有其他东西。 【参考方案1】:错误是由于调用UseBrowserLink()
,您可以从相关菜单管理此功能。
如果您取消选中启用浏览器链接,错误就会消失。
我不知道问题的原因,但这里是UseBrowserLink docs的链接
【讨论】:
也许您可以扩展您的答案以解释导致此错误的浏览器链接在此处执行的操作?【参考方案2】:我遇到了类似的问题。后来发现这个问题和使用中间件的顺序有关。我正在使用中间件来编写响应标头,例如 X-Content-Type-Options
和其他标头。我刚刚把它移到了app.UseStatusCodePagesWithReExecute
上面,它就开始正常工作了。所以我现在的代码是这样的:
app.Use(async (context, next) =>
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
context.Response.Headers.Add("X-Xss-Protection", "1");
context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
await next();
);
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
else
app.UseStatusCodePagesWithReExecute("/Home/Error/0");
希望这可以帮助任何像我一样遇到类似问题的人。
【讨论】:
帮了我很多忙!谢谢!【参考方案3】:我看到UseStatusCodePagesWithReExecute
指向一个不存在的端点,同时我试图获取一个标记为[HttpPost]
的端点。
【讨论】:
以上是关于解决错误 - “返回 404 时已添加具有相同键的项目”的主要内容,如果未能解决你的问题,请参考以下文章