I have a form that creates a ShopProduct, which is a join between a Shop and a Product.
The ShopProduct Create form sends up the ShopId/ProductId/etc. When the ShopProduct is received by the method, the Shop field is null (as expected). This was working fine, until I added this field to Shop:
[JsonIgnore, NotMapped, Display(Name = "Background Image")]
public IFormFile BackgroundImage { get; set; }
Now, despite the actual ShopProduct form not changing at all, the ShopProduct entity received by the Create method has a NON NULL Shop entity - a Shop with all of its values set to their defaults.
This is problematic because this shop isn't null, which means it causes the ModelState to become invalid.
So there seems to be something which is causing entities that have an IFormFile property to initialized where they shouldn't be.
Use ASP.Net Core 2.2
The child of a posted entity should be null if it isn't included in the form - regardless of whether the child has an IFormFile input.
If applicable, add screenshots to help explain your problem.
.NET Core SDK (reflecting any global.json):
Version: 2.2.103
Commit: 8edbc2570a
Runtime Environment:
OS Name: Windows
OS Version: 10.0.16299
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\2.2.103\
Host (useful for support):
Version: 2.2.1
Commit: 878dd11e62
As a (rather hacky) workaround, I created this class:
public class IFormFileWrapper
{
public IFormFile File { get; set; }
}
And then changed the property on Shop like so:
[JsonIgnore, NotMapped]
public IFormFileWrapper BackgroundImage { get; set; }
The ShopProduct.Shop field is now null again, as it should be - but I'd rather not have to use this silly wrapped instead of IFormFile directly!
Thanks for contacting us, @DanielStout5.
The reason for the Shop to be initialized for you is because of how the model binding treats the inner IFormFile property. If a greedy (that's the case here) model binder finds an applicable property in the value graph, it'll automatically initialize the parent object (to it's default value).
@pranavkm, can we investigate why the binding doesn't happen if the IFormFile property is further down in the tree?
It seems to me that the model binder shouldn't be greedy here - there is no value being posted by the form, so I don't understand why it would instantiate it. The Shop.BackgroundImage value itself was null - the form isn't sending up any files.
@DanielStout5 we made a few changes in this area as part of the 3.0 release. I verified that MVC no longer initializes sub-classes with IFormFile unless a value is present.
Most helpful comment
@DanielStout5 we made a few changes in this area as part of the 3.0 release. I verified that MVC no longer initializes sub-classes with
IFormFileunless a value is present.