提问人:ProfK 提问时间:11/24/2014 最后编辑:ProfK 更新时间:12/5/2014 访问量:1965
调用 Controller.Execute 时出现 NullReferenceException
NullReferenceException when calling Controller.Execute
问:
我遇到了一些通过派生控制器类调用的代码。但是,派生类不会重写,并且传入的参数不是 null,尽管它的几个属性是 null。如何确定问题的哪一部分是导致“执行”抛出的问题?Controller.Execute
ErrorController
Execute
RequestContext
RequestContext
NullReferenceException
下面是调用的代码:Execute
public class AuthenticationManager : ClaimsAuthenticationManager
{
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
try
{
throw new Exception();
if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated)
{
signInClient.TransformClaimsBasedOnUserRole(incomingPrincipal.Identity.AsClaimsBasedIdentitiy());
}
return base.Authenticate(resourceName, incomingPrincipal);
}
catch (Exception e)
{
var context = HttpContext.Current;
var routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
routeData.Values.Add("errorId", logId);
routeData.Values.Add("exceptionMessage", "");
IController controller = new ErrorController();
var ctx = new RequestContext(new HttpContextWrapper(context), routeData);
controller.Execute(ctx);
}
}
}
我不得不滑入投掷以重现异常。另一个授权代码仅在极少数情况下抛出。Execute
根据要求:
public class ErrorController: Controller
{
public ActionResult Index(Guid? errorId, string exceptionMessage)
{
ErrorModel resultModel;
try
{
resultModel = new ErrorModel
{
ErrorId = errorId==null ? Guid.NewGuid() : Guid.Parse(errorId.ToString()) ,
ErrorMessage = (string.IsNullOrEmpty(exceptionMessage)) ? ConfigurationManager.AppSettings["GenericError"] : exceptionMessage,
};
if (User.IsInRole(RoleIdentifiers.InActive))
{
Authentication.AuthenticationManager.SignOut();
}
}
catch (Exception e)
{
LogProvider.Current.LogError(LogLevel.Fatal, e, "Error constructing error result model for error Id [{0}]", errorId);
return new HttpNotFoundResult();
}
return View(resultModel);
}
public ActionResult SessionTimeOut(string rtnController = "Home", string rtnAction="Index")
{
return View(new SessionTimeOutViewModel { RedirectAction = rtnAction, RedirectController = rtnController });
}
public ActionResult LogonAgain()
{
return null;
}
}
而且,期待已久的堆栈跟踪:
at System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext)
at System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext)
at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
at MyCompany.Authentication.AuthenticationManager.Authenticate(String resourceName, ClaimsPrincipal incomingPrincipal) in c:\Development\Give4GoodGallery\ThreeFifteen.Plexus.Web\Authentication\AuthenticationManager.cs:line 63
仔细观察,我发现这看起来是关于 - 当直接调用时,可能会出现某种不存在的上下文。AuthorizeAttribute
Execute
答:
我能够毫无例外地执行您的代码,尽管您的具体情况可能会有所不同。
我不确定,如果你已经这样做了,如果你在Visual Studio中这样做了,那么:
1) 包装代码:在尝试中...catch 块,以便您应该能够看到异常详细信息。您可以单击异常窗口底部的“查看详细信息”,以便在新窗口中查看完整的异常详细信息,如 InnerException、StackTrace 等。它们可以帮助您缩小例外范围。controller.Execute(ctx);
2)在ErrorController的Index操作中放置一个断点,以便您可以通过点击“F10”来逐行执行检查:是否首先调用了ErrorController,并检查是否有任何代码引发异常。
但是,您可以交叉检查的基本区域是:
1) “索引”操作中的代码 [您通过以下方式进行设置:
routeData.Values.Add("action", "Index");
] 可能有一些未初始化的对象可能会抛出。
2)从ErrorController的Index操作返回的视图存在于正确的View文件夹中。
3)如果错误视图按预期存在,则在视图中检查它是否未引用任何未初始化的对象。
评论
Execute
base.Execute()
如何确定 RequestContext 的哪一部分是问题 使“执行”抛出 NullReferenceException?
- 在 Execute 调用行上放置断点
- 在 Visual Studio 中启用异常时自动中断 (调试 -> 异常... -> 公共语言运行时异常 -> 系统 -> System.NullReferenceException -> '检查抛出的复选框')
- 按 F5 继续执行程序并等待引发异常
- 获取异常的堆栈跟踪或打开调用堆栈窗口(调试 -> Windows ->调用堆栈)
- 从最顶层的调用中,您必须隔离您尝试对其执行操作的未初始化的变量。为此,您可以使用“自动”窗口(“调试”->“Windows”->“自动”)或“监视”窗口(“调试”-> “Windows”->“监视”)来检查当前变量(但不是 lambda)的内容,并找出哪个变量为 null。
查看堆栈跟踪,可以看出异常被抛出。这是一种简单的方法,它将访问 的属性以及此用户属性的属性。据我所知,这些属性之一必须为 null 才能抛出。AuthorizeAttribute.AuthorizeCore
User
HttpContextBase
Identity
NullReferenceException
最有可能的是 的属性为 null。这似乎并不奇怪,因为您正在调用我假设是身份验证过程的一部分。在此过程完成之前,用户是未知的。User
HttpContext.Current
ErrorController
AuthenticationManager
因此,您可以通过确保在调用之前知道用户来解决您的问题,但真正的问题是为什么需要授权?最好的解决方案可能是确保这不需要授权。这将允许您在授权之前或期间发生错误时调用控制器。ErrorController
ErrorController
ErrorController
评论
ErrorController
您是否正在尝试从正在运行的应用程序调用此方法?还是来自单元测试或除 MVC 运行时之外 asp.net 任何其他内容? 如果第一个是真的,那么这里是我能想到的可能导致 NRE 的任何东西,但如果第二个是真的,那么请确保 User 属性是具有值的提供者。
HttpContextBase GetContext(string userName)
{
var user = new GenericPrincipal(new GenericIdentity(userName, "Forms"), new string[] {});
var contextMock = new Mock<HttpContextBase>();
contextMock.Setup(context => context.User).Returns(user);
contextMock.Setup.....
return contextMock.Object;
}
评论
null
评论
ErrorController
Controller
ErrorController
IController.Execute()
dotPeek
ControllerBase