我有一个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);
}
答案 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上工作,而其他人不能。