示例#1
0
    public async Task FormFileModelBinder_UsesFieldNameForTopLevelObject(bool isTopLevel, string expected)
    {
        // Arrange
        var formFiles = new FormFileCollection
        {
            GetMockFormFile("FieldName", "file1.txt"),
            GetMockFormFile("ModelName", "file1.txt")
        };
        var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));

        var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);

        bindingContext.IsTopLevelObject = isTopLevel;
        bindingContext.FieldName        = "FieldName";
        bindingContext.ModelName        = "ModelName";

        var binder = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);
        var file = Assert.IsAssignableFrom <IFormFile>(bindingContext.Result.Model);

        Assert.Equal(expected, file.Name);
    }
示例#2
0
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            //绑定 对象部分
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            // Retrieve the form part containing the JSON
            var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);

            if (valueResult == ValueProviderResult.None)
            {
                // The JSON was not found
                var message = bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(bindingContext.FieldName);
                bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, message);
                return;
            }

            var rawValue = valueResult.FirstValue;

            // Deserialize the JSON
            var model = JsonConvert.DeserializeObject(rawValue, bindingContext.ModelType, _jsonOptions.Value.SerializerSettings);

            // Now, bind each of the IFormFile properties from the other form parts
            foreach (var property in bindingContext.ModelMetadata.Properties)
            {
                //if (property.ModelType != typeof(IFormFile))
                if (property.ModelType != typeof(IFormFile))
                {
                    continue;
                }

                var fieldName     = property.BinderModelName ?? property.PropertyName;
                var modelName     = fieldName;
                var propertyModel = bindingContext.ValueProvider.GetValue(fieldName);
                //var propertyModel = property.PropertyGetter(bindingContext.Model);
                ModelBindingResult propertyResult;
                using (bindingContext.EnterNestedScope(property, fieldName, modelName, propertyModel))
                {
                    await _formFileModelBinder.BindModelAsync(bindingContext);

                    propertyResult = bindingContext.Result;
                }

                if (propertyResult.IsModelSet)
                {
                    // The IFormFile was sucessfully bound, assign it to the corresponding property of the model
                    property.PropertySetter(model, propertyResult.Model);
                }
                else if (property.IsBindingRequired)
                {
                    var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName);
                    bindingContext.ModelState.TryAddModelError(modelName, message);
                }
            }

            // Set the successfully constructed model as the result of the model binding
            bindingContext.Result = ModelBindingResult.Success(model);
        }
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(paramName: nameof(bindingContext));
            }

            //recupere a parte do formulario que contem o JSon
            var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);

            if (valueResult == ValueProviderResult.None)
            {
                // O JSon não foi encontrado
                var message = bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(bindingContext.FieldName);
                bindingContext.ModelState.TryAddModelError(key: bindingContext.ModelName, message);
                return;
            }

            var rawValue = valueResult.FirstValue;

            // desserializar o modelo JSON
            var model = JsonConvert.DeserializeObject(rawValue, bindingContext.ModelType, _jsonOptions.Value.SerializerSettings);

            //Agora, vincule cada uma das propriedades IFormFile das outras partes do formulário
            foreach (var property in bindingContext.ModelMetadata.Properties)
            {
                if (property.ModelType != typeof(IFormFile))
                {
                    continue;
                }

                var fieldName     = property.BinderModelName ?? property.PropertyName;
                var modelName     = fieldName;
                var propertyModel = property.PropertyGetter(bindingContext.Model);
                ModelBindingResult propertyResult;
                using (bindingContext.EnterNestedScope(property, fieldName, modelName, propertyModel))
                {
                    await _formFileModelBinder.BindModelAsync(bindingContext);

                    propertyResult = bindingContext.Result;
                }

                if (propertyResult.IsModelSet)
                {
                    // O IFormFile foi vinculado com sucesso, atribua - o à propriedade correspondente da propriedade do modelo PropertySetter
                    property.PropertySetter(model, propertyResult.Model);
                }
                else if (property.IsBindingRequired)
                {
                    var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName);
                    bindingContext.ModelState.TryAddModelError(key: modelName, message);
                }
            }

            //Defina o modelo construído com sucesso como resultado do modelo binding
            bindingContext.Result = ModelBindingResult.Success(model);
        }
示例#4
0
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);

            if (valueResult == ValueProviderResult.None)
            {
                string message = bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(bindingContext.FieldName);
                bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, message);
                return;
            }

            string rawValue = valueResult.FirstValue;

            object model = JsonSerializer.Deserialize(rawValue, bindingContext.ModelType);

            foreach (var property in bindingContext.ModelMetadata.Properties)
            {
                if (property.ModelType != typeof(IFormFile))
                {
                    continue;
                }

                string fieldName = property.BinderModelName ?? property.PropertyName;
                string modelName = fieldName;

                object propertyModel = property.PropertyGetter(bindingContext.Model);

                ModelBindingResult propertyResult;

                using (bindingContext.EnterNestedScope(property, fieldName, modelName, propertyModel))
                {
                    await _formFileModelBinder.BindModelAsync(bindingContext);

                    propertyResult = bindingContext.Result;
                }

                if (propertyResult.IsModelSet)
                {
                    property.PropertySetter(model, propertyResult.Model);
                }
                else if (property.IsBindingRequired)
                {
                    string message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName);
                    bindingContext.ModelState.TryAddModelError(modelName, message);
                }
            }

            bindingContext.Result = ModelBindingResult.Success(model);
        }
示例#5
0
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
            var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);

            if (valueResult == ValueProviderResult.None)
            {
                var message = bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(bindingContext.FieldName);
                bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, message);
                return;
            }
            var rawValue = valueResult.FirstValue;
            var options  = new JsonSerializerOptions {
                PropertyNameCaseInsensitive = true
            };
            var model = JsonSerializer.Deserialize(rawValue, bindingContext.ModelType, options);

            foreach (ModelMetadata property in bindingContext.ModelMetadata.Properties)
            {
                if (property.ModelType != typeof(IFormFile) &&
                    property.ModelType != typeof(IFormFile[]) &&
                    property.ModelType != typeof(List <IFormFile>))
                {
                    continue;
                }
                var fieldName     = property.BinderModelName ?? property.PropertyName;
                var modelName     = fieldName;
                var propertyModel = property.PropertyGetter(bindingContext.Model);
                ModelBindingResult propertyResult;
                using (bindingContext.EnterNestedScope(property, fieldName, modelName, propertyModel))
                {
                    await formFileModelBinder.BindModelAsync(bindingContext).ConfigureAwait(false);

                    propertyResult = bindingContext.Result;
                }
                if (propertyResult.IsModelSet)
                {
                    property.PropertySetter(model, propertyResult.Model);
                }
                else if (property.IsBindingRequired)
                {
                    var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName);
                    bindingContext.ModelState.TryAddModelError(modelName, message);
                }
            }
            bindingContext.Result = ModelBindingResult.Success(model);
        }
示例#6
0
    public async Task FormFileModelBinder_ReturnsResult_ForReadOnlyDestination()
    {
        // Arrange
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);
        var formFiles      = GetTwoFiles();
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContextForReadOnlyArray(httpContext);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);
        Assert.NotNull(bindingContext.Result.Model);
    }
示例#7
0
    public async Task FormFileModelBinder_ReturnsFailedResult_ForCollectionsItCannotCreate()
    {
        // Arrange
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);
        var formFiles      = GetTwoFiles();
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContext(typeof(ISet <IFormFile>), httpContext);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.False(bindingContext.Result.IsModelSet);
        Assert.Null(bindingContext.Result.Model);
    }
示例#8
0
    public async Task FormFileModelBinder_BindsFiles_ForCollectionsItCanCreate(Type destinationType)
    {
        // Arrange
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);
        var formFiles      = GetTwoFiles();
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContext(destinationType, httpContext);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);
        Assert.IsAssignableFrom(destinationType, bindingContext.Result.Model);
        Assert.Equal(formFiles, bindingContext.Result.Model as IEnumerable <IFormFile>);
    }
示例#9
0
    public async Task FormFileModelBinder_ExpectSingleFile_BindFirstFile()
    {
        // Arrange
        var formFiles      = GetTwoFiles();
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);
        var file = Assert.IsAssignableFrom <IFormFile>(bindingContext.Result.Model);

        Assert.Equal("file1.txt", file.FileName);
    }
示例#10
0
    public async Task FormFileModelBinder_ReturnsFailedResult_WithNoFileNameAndZeroLength()
    {
        // Arrange
        var formFiles = new FormFileCollection
        {
            GetMockFormFile("file", "")
        };
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.False(bindingContext.Result.IsModelSet);
        Assert.Null(bindingContext.Result.Model);
    }
示例#11
0
    public async Task FormFileModelBinder_ReturnsFailedResult_WhenNamesDoNotMatch()
    {
        // Arrange
        var formFiles = new FormFileCollection
        {
            GetMockFormFile("different name", "file1.txt")
        };
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.False(bindingContext.Result.IsModelSet);
        Assert.Null(bindingContext.Result.Model);
    }
示例#12
0
    public async Task FormFileModelBinder_ReturnsFailedResult_WithEmptyContentDisposition()
    {
        // Arrange
        var formFiles = new FormFileCollection
        {
            new Mock <IFormFile>().Object
        };
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.False(bindingContext.Result.IsModelSet);
        Assert.Null(bindingContext.Result.Model);
    }
示例#13
0
    public async Task FormFileModelBinder_SingleFileWithinTopLevelPoco_BindSuccessfully_WithShortenedModelName()
    {
        // Arrange
        const string propertyName = nameof(NestedFormFiles.Files);
        var          formFiles    = new FormFileCollection
        {
            GetMockFormFile($"FileList.{propertyName}", "file1.txt")
        };

        var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
        var binder      = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Mimic ParameterBinder overwriting ModelName on top level model then ComplexTypeModelBinder entering a
        // nested context for the NestedFormFiles property. In this non-top-level binding case, FormFileModelBinder
        // tries ModelName then falls back to add an (OriginalModelName + ".") prefix.
        var propertyInfo = typeof(NestedFormFiles).GetProperty(propertyName);
        var metadata     = new EmptyModelMetadataProvider().GetMetadataForProperty(
            propertyInfo,
            propertyInfo.PropertyType);
        var bindingContext = DefaultModelBindingContext.CreateBindingContext(
            new ActionContext {
            HttpContext = httpContext
        },
            Mock.Of <IValueProvider>(),
            metadata,
            bindingInfo: null,
            modelName: "FileList");

        bindingContext.IsTopLevelObject = false;
        bindingContext.Model            = new FileList();
        bindingContext.ModelName        = propertyName;

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);

        var entry = bindingContext.ValidationState[bindingContext.Result.Model];

        Assert.False(entry.SuppressValidation);
        Assert.Equal($"FileList.{propertyName}", entry.Key);
        Assert.Null(entry.Metadata);
    }
示例#14
0
    public async Task FormFileModelBinder_SingleFileWithinTopLevelPoco_BindSuccessfully()
    {
        // Arrange
        const string propertyName = nameof(NestedFormFiles.Files);
        var          formFiles    = new FormFileCollection
        {
            GetMockFormFile($"{propertyName}", "file1.txt")
        };

        var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
        var binder      = new FormFileModelBinder(NullLoggerFactory.Instance);

        // In this non-top-level binding case, FormFileModelBinder tries ModelName and succeeds.
        var propertyInfo = typeof(NestedFormFiles).GetProperty(propertyName);
        var metadata     = new EmptyModelMetadataProvider().GetMetadataForProperty(
            propertyInfo,
            propertyInfo.PropertyType);
        var bindingContext = DefaultModelBindingContext.CreateBindingContext(
            new ActionContext {
            HttpContext = httpContext
        },
            Mock.Of <IValueProvider>(),
            metadata,
            bindingInfo: null,
            modelName: "FileList");

        bindingContext.IsTopLevelObject = false;
        bindingContext.Model            = new FileList();
        bindingContext.ModelName        = propertyName;

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);

        var entry = bindingContext.ValidationState[bindingContext.Result.Model];

        Assert.False(entry.SuppressValidation);
        Assert.Equal($"{propertyName}", entry.Key);
        Assert.Null(entry.Metadata);
    }
示例#15
0
    public async Task FormFileModelBinder_SingleFileWithinTopLevelDictionary_BindSuccessfully_WithShortenedModelName()
    {
        // Arrange
        var formFiles = new FormFileCollection
        {
            GetMockFormFile("FileDictionary[myFile]", "file1.txt")
        };

        var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
        var binder      = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Mimic ParameterBinder overwriting ModelName on top level model then DictionaryModelBinder entering a
        // nested context for the KeyValuePair.Value property. In this non-top-level binding case,
        // FormFileModelBinder tries ModelName then falls back to add an OriginalModelName prefix.
        var bindingContext = DefaultModelBindingContext.CreateBindingContext(
            new ActionContext {
            HttpContext = httpContext
        },
            Mock.Of <IValueProvider>(),
            new EmptyModelMetadataProvider().GetMetadataForType(typeof(IFormFile)),
            bindingInfo: null,
            modelName: "FileDictionary");

        bindingContext.IsTopLevelObject = false;
        bindingContext.ModelName        = "[myFile]";

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);

        var entry = bindingContext.ValidationState[bindingContext.Result.Model];

        Assert.False(entry.SuppressValidation);
        Assert.Equal("FileDictionary[myFile]", entry.Key);
        Assert.Null(entry.Metadata);
    }
示例#16
0
    public async Task FormFileModelBinder_SingleFile_BindSuccessful()
    {
        // Arrange
        var formFiles = new FormFileCollection
        {
            GetMockFormFile("file", "file1.txt")
        };
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContext(typeof(IEnumerable <IFormFile>), httpContext);
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);

        var entry = bindingContext.ValidationState[bindingContext.Result.Model];

        Assert.False(entry.SuppressValidation);
        Assert.Equal("file", entry.Key);
        Assert.Null(entry.Metadata);
    }
示例#17
0
    public async Task FormFileModelBinder_SingleFileAtTopLevel_BindSuccessfully_WithEmptyModelName()
    {
        // Arrange
        var formFiles = new FormFileCollection
        {
            GetMockFormFile("file", "file1.txt")
        };

        var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
        var binder      = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Mimic ParameterBinder overwriting ModelName on top level model. In this top-level binding case,
        // FormFileModelBinder uses FieldName from the get-go. (OriginalModelName will be checked but ignored.)
        var bindingContext = DefaultModelBindingContext.CreateBindingContext(
            new ActionContext {
            HttpContext = httpContext
        },
            Mock.Of <IValueProvider>(),
            new EmptyModelMetadataProvider().GetMetadataForType(typeof(IFormFile)),
            bindingInfo: null,
            modelName: "file");

        bindingContext.ModelName = string.Empty;

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);

        var entry = bindingContext.ValidationState[bindingContext.Result.Model];

        Assert.False(entry.SuppressValidation);
        Assert.Equal("file", entry.Key);
        Assert.Null(entry.Metadata);
    }
示例#18
0
    public async Task FormFileModelBinder_SingleFileWithinTopLevelDictionary_BindSuccessfully()
    {
        // Arrange
        var formFiles = new FormFileCollection
        {
            GetMockFormFile("[myFile]", "file1.txt")
        };

        var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
        var binder      = new FormFileModelBinder(NullLoggerFactory.Instance);

        // In this non-top-level binding case, FormFileModelBinder tries ModelName and succeeds.
        var bindingContext = DefaultModelBindingContext.CreateBindingContext(
            new ActionContext {
            HttpContext = httpContext
        },
            Mock.Of <IValueProvider>(),
            new EmptyModelMetadataProvider().GetMetadataForType(typeof(IFormFile)),
            bindingInfo: null,
            modelName: "FileDictionary");

        bindingContext.IsTopLevelObject = false;
        bindingContext.ModelName        = "[myFile]";

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);

        var entry = bindingContext.ValidationState[bindingContext.Result.Model];

        Assert.False(entry.SuppressValidation);
        Assert.Equal("[myFile]", entry.Key);
        Assert.Null(entry.Metadata);
    }
示例#19
0
    public async Task FormFileModelBinder_ExpectMultipleFiles_BindSuccessful()
    {
        // Arrange
        var formFiles      = GetTwoFiles();
        var httpContext    = GetMockHttpContext(GetMockFormCollection(formFiles));
        var bindingContext = GetBindingContext(typeof(IEnumerable <IFormFile>), httpContext);
        var binder         = new FormFileModelBinder(NullLoggerFactory.Instance);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);

        var entry = bindingContext.ValidationState[bindingContext.Result.Model];

        Assert.False(entry.SuppressValidation);
        Assert.Equal("file", entry.Key);
        Assert.Null(entry.Metadata);

        var files = Assert.IsAssignableFrom <IList <IFormFile> >(bindingContext.Result.Model);

        Assert.Equal(2, files.Count);
    }
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            // Retrieve the form part containing the JSON
            var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);

            if (valueResult == ValueProviderResult.None)
            {
                // The JSON was not found
                var message = bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(bindingContext.FieldName);
                bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, message);


                var initialBody = bindingContext.HttpContext.Request.Body; // Workaround

                bindingContext.HttpContext.Request.EnableBuffering();
                var buffer = new byte[Convert.ToInt32(bindingContext.HttpContext.Request.ContentLength)];
                await bindingContext.HttpContext.Request.Body.ReadAsync(buffer, 0, buffer.Length);

                var json = Encoding.UTF8.GetString(buffer);
                bindingContext.HttpContext.Request.Body = initialBody;
                var modelFromBody = JsonConvert.DeserializeObject(json, bindingContext.ModelType, _jsonOptions.Value.SerializerSettings);
                bindingContext.Result = ModelBindingResult.Success(modelFromBody);
                return;
            }

            var rawValue = valueResult.FirstValue;

            // Deserialize the JSON
            var model = JsonConvert.DeserializeObject(rawValue, bindingContext.ModelType, _jsonOptions.Value.SerializerSettings);

            // Now, bind each of the IFormFile properties from the other form parts
            foreach (var property in bindingContext.ModelMetadata.Properties)
            {
                if (property.ModelType != typeof(IFormFile) && property.ModelType != typeof(ICollection <IFormFile>) && property.ModelType != typeof(IEnumerable <IFormFile>))
                {
                    continue;
                }

                var fieldName     = property.BinderModelName ?? property.PropertyName;
                var modelName     = fieldName;
                var propertyModel = property.PropertyGetter(bindingContext.Model);
                ModelBindingResult propertyResult;
                using (bindingContext.EnterNestedScope(property, fieldName, modelName, propertyModel))
                {
                    await _formFileModelBinder.BindModelAsync(bindingContext);

                    propertyResult = bindingContext.Result;
                }

                if (propertyResult.IsModelSet)
                {
                    // The IFormFile was sucessfully bound, assign it to the corresponding property of the model
                    property.PropertySetter(model, propertyResult.Model);
                }
                else if (property.IsBindingRequired)
                {
                    var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName);
                    bindingContext.ModelState.TryAddModelError(modelName, message);
                }
            }

            // Set the successfully constructed model as the result of the model binding
            bindingContext.Result = ModelBindingResult.Success(model);
        }