【问题标题】:ASP.NET 2.2 Core Add user to a model throws nullreference exceptionASP.NET 2.2 Core 将用户添加到模型会引发空引用异常
【发布时间】:2019-06-13 14:48:33
【问题描述】:

我有一个具有 ApplicationUser 类型的属性 Publisher 的模型。当我尝试创建模型时,它给了我一个空引用异常。

在模型中:

[Display(Name = "Publisher")]
[ForeignKey("PublisherId")]
public ApplicationUser Publisher { get; set; }

在应用程序用户中:

public ICollection<Model> PublishedModels { get; set; }

数据库上下文中的多对一关系:

b.HasMany(u => u.PublishedModels)
     .WithOne(v => v.Publisher)
     .IsRequired()
     .OnDelete(DeleteBehavior.Restrict);

在控制器的Create方法中(获取当前用户):

var user = await _userManager.GetUserAsync(HttpContext.User);

我在这一行得到一个空引用:

model.Publisher = user;

我很困惑,我验证了用户不为空。 Model 不为 null 且 ModelState 有效。那为什么我不能将该值分配给model.Publisher?奇怪的是,如果我不修改模型并将其保存到数据库中,它就可以工作。但我也需要添加发布者。如果我只设置日期也可以。

这可行,但是在删除 cmets 时,它会在设置日期时抱怨空引用。

public async Task<IActionResult> Create([Bind(include:"...")] Model model)
{
    ApplicationUser user = await _userManager.GetUserAsync(HttpContext.User);
    try
    {
        if (ModelState.IsValid)
        {
            model.PublicationDate = DateTime.Now;

            //user.PublishedModels.Add(model);

            _context.Add(model);
            //_context.Update(model.Publisher);

            await _context.SaveChangesAsync();

            return RedirectToAction(nameof(Index));
        }
    }
    catch (DataException /*dex*/)
    {
        ModelState.AddModelError("", "...");
    }
    return View(model);
}

在下面的堆栈跟踪中,它在方法的第一行崩溃...

NullReferenceException: Object reference not set to an instance of an object.
WebApp.Controllers.Admin.ModelController.Create(Model model) in 
ModelController.cs
-
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind(include:"...")] Model model)
{
    var user = await _userManager.GetUserAsync(HttpContext.User);
    user.PublishedModels.Add(model);
    model.PublicationDate = DateTime.Now;
    model.Publisher = user;
    try
    { 
Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor+TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)

System.Threading.Tasks.ValueTask.get_Result() Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync() Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync() Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext 上下文) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext 上下文) Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文) Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext 上下文) Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext 上下文) Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext 上下文) Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext 上下文) Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext 上下文) Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext) Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

【问题讨论】:

  • 唯一可能在该行引发此异常的是model 是否为空。 model 为空,异常是从不同的地方抛出的,或者你有一些奇怪的事情发生,比如抛出异常的自定义 getter/setter。发布您的堆栈跟踪。
  • 没有自定义 getter。就像我必须以该方法将模型保存到数据库一样,似乎不接受我修改发布的模型。也许它与防伪有关?
  • 这似乎不是完整的堆栈跟踪。看起来你已经修改了它。特别是它没有调用任何特定的行。
  • 我修改了模型的名称。问题是没有空引用。当我添加代码以获取用户时,它会正确获取它,我可以看到该值。然后下一行失败,不管它是哪一行。如果我删除与用户相关的代码,它就可以工作。我使用经过身份验证的用户执行此操作。

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


【解决方案1】:

无法重现您的问题,请检查您的代码与以下代码之间的差异:

  1. 您在ApplicationUser 中定义了PublishedModels,但您引用了PublishedModel
  2. DbContext,对于下面的代码,如果您在创建Model 时没有设置PublisherPublisherId 的值,则会出现错误,因为您没有设置PublisherId 的值,但是您没有,请检查您是否保持模型和数据库相同。

            builder.Entity<ApplicationUser>()
                    .HasMany(u => u.PublishedModels)
                    .WithOne(vv => vv.Publisher)
                    .IsRequired()
                    .OnDelete(DeleteBehavior.Restrict);
    
  3. 用applicationuser创建模型的方法

            public async Task<IActionResult> Create([Bind("Id,Name")] Model model)
            {
                    ApplicationUser user = await _userManager.GetUserAsync(HttpContext.User);
                    if (ModelState.IsValid)
                    {
                            model.Publisher = user;
                            _context.Add(model);
                            await _context.SaveChangesAsync();
                            return RedirectToAction(nameof(Index));
                    }
                    return View(model);
            }
    

【讨论】:

  • 感谢您的关注 +1。这是一个非常奇怪的问题,拥有一个空引用并没有多大意义。就好像行为是未定义的。我搭建了控制器和视图,然后添加了用户属性并编辑了控制器。我无法让它工作。我最终再次搭建了所有脚手架,现在它可以在不更改控制器的情况下工作。但是我必须在表单中绑定外键。我将尝试编辑新搭建的控制器,看看是否可以删除绑定并在创建时设置它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
  • 2017-01-13
  • 1970-01-01
相关资源
最近更新 更多