我有一个创建子实体的Web应用程序控制器操作。我有一个带有LocationPic集合的Location模型。我正在尝试将新的LocationPic添加到现有位置。本地工作正常,但是当我在Azure上运行它时,会创建LocationPic但不引用该位置。所以我最终得到了一个孤立的LocationPic,它不知道它属于哪个位置。
此外,它在本地工作正常,并在Azure上为ALREADY有图片的位置(我有一个单独的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”正确显示。另外,我得到正确的重定向回编辑操作,而不是BadRequest或任何东西。
在本地,我注意到的唯一区别是没有图片的Location有一个LocationPics是一个空集合,Count == 0。在Azure上,没有图片的位置似乎有一个为null的LocationPics。所以这就是为什么我尝试添加初始化它的位,如果它是null,虽然我的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);
}
结果显示位置图片正常,但在我显示它们的控制器操作中我没有使用.Include()来包含LocationPics集合?除了它适用于以前有位置图片的地点吗?它在当地完全适合一切。所以我不完全确定。
一旦我把.Include()包含在我的“EditByLocation”控制器动作中的LocationPics集合,该动作按ID抓取一个位置并将其发送到显示该位置的位置和图片的视图,所有以前的图片我都会添加到我认为没有得到它们的位置上。所以出于某种原因,位置A(带图片)显示其图片很好,但位置B(显然有图片但我直到现在看不到它们)没有显示它们。我没有理由相信这些位置没有正确显示,因为有些显示正常,而其他人则使用null 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上工作而没有它而不是其他位置