首页 > 解决方案 > 添加子实体在本地有效,但在实时 Azure 站点上无效

问题描述

我有一个正在创建子实体的 Web 应用程序控制器操作。我有一个带有 LocationPic 集合的 Location 模型。我正在尝试将新的 LocationPic 添加到现有位置。在本地这工作正常,但是当我在 Azure 上运行它时,会创建 LocationPic 但不引用位置。所以我最终得到了一个不知道它属于哪个位置的孤立 LocationPic。

此外,对于已经有图片的位置,它在本地和 Azure 上都可以正常工作(我有一个单独的 API 控制器,似乎工作正常)。所以我可以将新图片添加到已经有一些的位置。但我无法将新照片添加到没有任何照片的新位置。

这是我的控制器操作:

// POST: Pictures/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("LocationID,Name,Description")] LocationPic locationPic, IFormFile image)
{
    var location = await _context.Locations.FindAsync(locationPic.LocationID);
    if (location == null)
    {
        return NotFound();
    }

    Trace.TraceInformation($"Create Pic for location[{location.LocationID}:{location.LocationName}]");

    _userService = new UserService((ClaimsIdentity)User.Identity, _context);
    if (!_userService.IsAdmin)
    {
        return Unauthorized();
    }

    if (image == null)
    {
        return BadRequest();
    }

    if (String.IsNullOrEmpty(locationPic.Name))
    {
        locationPic.Name = image.FileName;
    }

    var helper = new AzureTools();
    var filename = await helper.GetFileName(image);

    locationPic.FileName = filename;

    //Added this to try to force LocationPics to be initialized
    if (location.LocationPics == null)
    {
        Trace.TraceInformation("location.LocationPics is null");
        location.LocationPics = new List<LocationPic>();
    }
    else
    {
        Trace.TraceInformation($"location.LocationPics count == {location.LocationPics.Count}");
    }

    if (ModelState.IsValid)
    {
        Trace.TraceInformation($"Location pic valid: [{locationPic.LocationID}] {locationPic.Name}");
        //Overly-explicit attempts to get entities linked
        locationPic.Location = location;
        location.LocationPics.Add(locationPic);
        //I've tried _context.LocationPics.Add as well and seemingly no difference
        _context.Add(locationPic);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Edit), new { locationID = location.LocationID });
    } else
    {
        Trace.TraceInformation("Invalid model state");
        return BadRequest();
    }
}

所有正确的信息似乎都从我的表单正确地进入了我的参数,并且 LocationPic 被创建得很好。尽管“LocationID”在保存之前正确显示,但它只是没有链接到位置。另外,我得到了正确的重定向回 Edit 操作,而不是 BadRequest 或任何东西。

在本地,我注意到的唯一区别是没有图片的 Location 有一个 LocationPics,它是一个 Count==0 的空集合。在 Azure 上,没有图片的位置似乎有一个为空的 LocationPics。所以这就是为什么我尝试添加初始化它的位(如果它为空),尽管我的工作的 API 控制器不需要做任何事情。

这是我的(工作)API 控制器操作,供参考:

[HttpPost("{id}", Name = "PostPicture")]
public async Task<IActionResult> PostPicture([FromRoute] int id, IFormFile image, string Name, string Description)
{
    var location = _context.Locations.Find(id);
    if (location == null)
    {
        return NotFound();
    }

    _userService = new UserService((ClaimsIdentity)User.Identity, _context);
    if (!_userService.IsCustomer(location.CustomerID))
    {
        return Unauthorized();
    }

    if (image == null)
    {
        return BadRequest();
    }

    if (String.IsNullOrEmpty(Name))
    {
        Name = image.FileName;
    }

    var helper = new AzureTools();
    var filename = await helper.GetFileName(image);

    var locationPic = new LocationPic
    {
        Name = Name,
        FileName = filename,
        Description = Description,
        Location = location
    };

    _context.LocationPics.Add(locationPic);
    _context.SaveChanges();
    return Ok(filename);
}

标签: asp.net-mvcazureasp.net-coreentity-framework-coreasp.net-core-2.1

解决方案


结果发现位置图片运行良好,但是在我显示它们的控制器操作中,我没有使用 .Include() 来包含 LocationPics 集合?除了它适用于以前有位置图片的位置吗?它在当地对一切都很好。所以我不完全确定。

一旦我将 .Include() 包含在我的“EditByLocation”控制器操作中的 LocationPics 集合中,该操作通过 ID 获取位置并将其发送到显示该位置的位置和图片的视图,所有以前的图片我会添加突然出现在我认为没有得到它们的位置上。因此,出于某种原因,位置 A(有图片)可以正常显示其图片,但位置 B(显然有图片,但我直到现在才看到)没有显示它们。我没有理由相信这些位置没有正确显示,因为有些显示正常,而另一些则带有一个空的 LocationPics 集合。所以这对我来说毫无意义。但它现在似乎正在工作。

为了完整起见,这是我的最终控制器操作代码,您可能会注意到它与 API 控制器操作非常相似,这就是它开始时的样子:

// POST: Pictures/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("LocationID,Name,Description")] LocationPic locationPic, IFormFile image)
{
    var location = await _context.Locations.FindAsync(locationPic.LocationID);
    if (location == null)
    {
        return NotFound();
    }

    _userService = new UserService((ClaimsIdentity)User.Identity, _context);
    if (!_userService.IsAdmin)
    {
        return Unauthorized();
    }

    if (image == null)
    {
        return BadRequest();
    }

    if (String.IsNullOrEmpty(locationPic.Name))
    {
        locationPic.Name = image.FileName;
    }

    var helper = new AzureTools();
    var filename = await helper.GetFileName(image);

    locationPic.FileName = filename;

    if (ModelState.IsValid)
    {
        locationPic.Location = location;
        _context.LocationPics.Add(locationPic);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(EditByLocation), new { locationID = location.LocationID });
    }             

    return View("EditByLocation", location);
}

这是我的新 EditByLocation 控制器操作:

// GET: Pictures/EditByLocation?locationID=5
public async Task<IActionResult> EditByLocation(int locationID)
{
    _userService = new UserService((ClaimsIdentity)User.Identity, _context);
    if (!_userService.IsAdmin)
    {
        return Unauthorized();
    }

    ViewData["ImageBaseUrl"] = _config["AzureStorage:Url"] + "/" + _config["AzureStorage:Folder"];

    var location = await _context.Locations.Include(l => l.LocationPics).FirstOrDefaultAsync(l => l.LocationID == locationID);

    if (location == null)
    {
        return NotFound();
    }

    if (location.LocationPics == null)
    {
        location.LocationPics = new List<LocationPic>();
    }

    return View("EditByLocation", location);
}

上面唯一真正的变化是添加了 .Include(l => l.LocationPics)。再说一次,不知道为什么它在没有它的情况下在本地工作,以及为什么有些地方在没有它的情况下在 Azure 上工作,而在其他地方却不行。


推荐阅读