添加子实体可在本地工作,但不能在实时Azure网站上使用

时间:2019-03-20 18:03:40

标签: asp.net-mvc azure asp.net-core entity-framework-core asp.net-core-2.1

我有一个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上,没有图片的位置似乎具有一个null的LocationPics。因此,尽管我的API控制器不需要执行任何操作,所以我尝试添加一个用于将其初始化为null的位的原因。

这是我(正在工作的)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);
}

1 个答案:

答案 0 :(得分:0)

结果证明位置图片运行良好,但是在显示它们的控制器操作中,我没有使用.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上工作,而其他人不能。