【问题标题】:Why is my element variable always null in this foreach loop?为什么我的元素变量在这个 foreach 循环中总是为空?
【发布时间】:2012-03-22 17:07:45
【问题描述】:

代码如下:

public IEnumerable<UserSummary> getUserSummaryList()
{
    var db = new entityContext();
    List<UserSummary> model = new List<UserSummary>();

    List<aspnet_Users> users = (from user in db.aspnet_Users
                 select user).ToList<aspnet_Users>();
    foreach (aspnet_Users u in users) //u is always null while users is a list that contains 4 objects
    {
        model.Add(new UserSummary()
        {
            UserName = u.UserName,
            Email = u.aspnet_Membership.Email,
            Role = Roles.GetRolesForUser(u.UserName).First(),
            AdCompany = u.AD_COMPANIES.ad_company_name != null ? u.AD_COMPANIES.ad_company_name : "Not an Advertiser",
            EmployeeName = u.EMPLOYEE.emp_name != null ? u.EMPLOYEE.emp_name : "Not an Employee"
        });
    }

    return model;
}

由于某种原因,foreach 循环中的u 变量始终为空。我已经逐步完成了代码,并且始终填充了 users 集合。 db.aspnet_Users 的表实体是 asp.net 会员服务附带的 users 表。我只添加了几个关联。

编辑:调试器的图像

这是堆栈跟踪:

[NullReferenceException: Object reference not set to an instance of an object.]
   OutAd.Models.AccountMembershipService.getUserSummaryList() in C:\Users\stephen\Desktop\outad\OutAd\OutAd\Models\AccountModels.cs:301
   OutAd.Controllers.AdminController.UserList() in C:\Users\stephen\Desktop\outad\OutAd\OutAd\Controllers\AdminController.cs:78
   lambda_method(Closure , ControllerBase , Object[] ) +96
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
   System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.Mvc.<>c__DisplayClassa.<EndProcessRequest>b__9() +23
   System.Web.Mvc.<>c__DisplayClass4.<Wrap>b__3() +12
   System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +38
   System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Action action) +65
   System.Web.Mvc.ServerExecuteHttpHandlerAsyncWrapper.EndProcessRequest(IAsyncResult result) +71
   System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +1072

[HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.]
   System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +3049403
   System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +77
   System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +28
   System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +22
   System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +497
   System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues) +88
   System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName) +10
   ASP._Page_Views_Admin_Users_cshtml.Execute() in c:\Users\stephen\Desktop\outad\OutAd\OutAd\Views\Admin\Users.cshtml:7
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +207
   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +81
   System.Web.WebPages.StartPage.RunPage() +19
   System.Web.WebPages.StartPage.ExecutePageHierarchy() +65
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +76
   System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +220
   System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115
   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +303
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
   System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +23
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260
   System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8969201
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

【问题讨论】:

  • 别忘了释放上下文!
  • 老实说,在我看来不太可能。听起来它更有可能是调试/诊断问题。
  • 这不可能,当您尝试访问u 的属性时,如果它确实为空,您会得到一个 NullReferenceException。
  • 这里只是一个随机的想法,但默认情况下,列表中有 4 个空条目。您能否确认这些条目包含实际数据还是全部为空?
  • 不要冒犯,伙计们。有一天,我们每个人都有一种奇怪的代码行为。

标签: c# .net entity-framework asp.net-membership


【解决方案1】:

替换:

Roles.GetRolesForUser(u.UserName)

作者:

Roles.Provider.GetRolesForUser(u.UserName);

cfr.:http://www.lhotka.net/weblog/CallingRolesGetRolesForUserInAWCFService.aspx

【讨论】:

    【解决方案2】:

    我猜u 本身不是空的,但它的属性之一是空,或者Roles.GetRolesForUser(u.UserName) 调用返回空。如果是这种情况,那么当您尝试访问这些空值的成员时,您会得到 NullReferenceException。

    例子:

    public class Person
    {
        public Address HomeAddress { get; set; }
    }
    
    public class Address
    {
        public String StreetAddress { get; set; }
    }
    
    public void SomeFunc()
    {
        var person = new Person();
    
        //NullReferenceException because HomeAddress is null.
        //NOT because person is null...
        var address = person.HomeAddress.StreetAddress;
    }
    

    您可以通过将鼠标悬停在调试器中的每个项目上来验证这一点,以确保它不为空,但我敢打赌,其中一个对象是。为确保您的 GetRolesForUser 方法不返回 null,只需在即时窗口中调用它并查看您返回的内容。如果你返回 null,那就是你的问题。

    或者,只需将每个右手作业放入本地观察窗口,其中一个就会显示为问题。


    哦,还有其他一些事情......

    1. 如果您打算返回 IEnumerable&lt;T&gt;,请不要创建列表然后返回该列表,而只需 yield return 您的对象。

    2. 必要时使用空合并运算符。

    3. 为您的IDisposable 对象使用using 语句。

    固定版本:

    public IEnumerable<UserSummary> getUserSummaryList()
    {
        using (var db = new EntityContext())
        {
            foreach (aspnet_Users user in users)
            {
                // Retrieve the username (with logic if it is null or empty)
                var username = user.UserName;
    
                // Retrieve the email (with logic if it is null or empty)
                var email = (user.aspnet_Membership != null)
                    ? user.aspnet_Membership.Email ?? String.Empty
                    : String.Empty;
    
                // Retrieve the role (with logic if it is null)
                var roles = Roles.GetRolesForUser(username);
                var role = (roles != null) ? roles.FirstOrDefault() : null;
    
                // Retrieve the Ad Company (with logic if it is null)
                var adCompany = (user.AD_COMPANIES != null)
                    ? user.AD_COMPANIES.ad_company_name ?? "Not an Advertiser"
                    : "Not an Advertiser";
    
                var empName = (user.EMPLOYEE != null)
                    ? user.EMPLOYEE.emp_name ?? "Not an Employee"
                    : "Not an Employee";
    
                yield return new UserSummary
                    {
                        UserName     = username,
                        Email        = email,
                        Role         = role,
                        AdCompany    = adCompany,
                        EmployeeName = empName,
                    };
            }
        }
    }
    

    【讨论】:

    • ??只是语法糖,它不会使代码好坏
    • @EvertonAgner:对我来说,“好”代码是更易读的代码,而空值合并比执行完全相同的三元运算符更易读。
    • 我知道,我的意思是您以“对或错”的方式陈述。
    猜你喜欢
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    相关资源
    最近更新 更多