Почему моя переменная элемента всегда равна нулю в этом цикле foreach? - PullRequest
2 голосов
/ 22 марта 2012

Вот код:

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;
}

По какой-то причине переменная u в цикле foreach всегда равна нулю. Я прошел через код, и коллекция users всегда заполнена. Сущность таблицы для db.aspnet_Users - это таблица пользователей, которая поставляется со службами членства asp.net. Я добавил только пару ассоциаций.

редактировать: изображение отладчика

debugger

Вот трассировка стека:

[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

Ответы [ 2 ]

4 голосов
/ 13 декабря 2012

Заменить:

Roles.GetRolesForUser(u.UserName)

По:

Roles.Provider.GetRolesForUser(u.UserName);

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

2 голосов
/ 22 марта 2012

Я собираюсь предположить, что 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 не возвращает ноль, просто вызовите его в ближайшем окне и посмотрите, что вы получите. Если вы вернетесь в ноль, это ваша проблема.

В качестве альтернативы, просто бросьте каждое из заданий правой руки в ваше местное окно наблюдения, и одно из них будет отображаться как проблема.


О, и еще несколько вещей ...

  1. Если вы планируете вернуть IEnumerable<T>, не создавайте список, а затем возвращайте этот список, вместо этого просто yield return ваши объекты.

  2. При необходимости используйте операторы объединения нулей.

  3. Используйте оператор using для ваших IDisposable объектов.

Фиксированная версия:

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,
                };
        }
    }
}
...