Загрузить файл, а также передать данные модели - PullRequest
0 голосов
/ 05 июня 2019

Мне нужно импортировать файл, а также модель Person, которую я показал ниже.

Я могу загрузить файл, однако я не могу получить данные модели Person вimportFileAndOtherInfo метод, который я написал.

Примечание: я тестирую этот веб-API через Почтальон.Как я могу загрузить файл, а также отправить Person данные модели через почтальона?

Person

int pId
string PName
School schoolAttended

Моя реализация:

[HttpPost]
public async Task<int> importFileAndOtherInfo(Person person)
{

    var stream = HttpContext.Current.Request.Files[0].InputStream

    // HOW TO RETRIEVE THE PERSON DATA HERE.

}

1 Ответ

0 голосов
/ 06 июня 2019

Из вашего вопроса я понял, что вы хотите передавать данные модели и файл в поток одновременно; Вы не можете отправить его напрямую, можно отправить файл с помощью IFormFile и добавить создать свой собственный механизм связывания следующим образом:

public class JsonWithFilesFormDataModelBinder: IModelBinder
{
    private readonly IOptions<MvcJsonOptions> _jsonOptions;
    private readonly FormFileModelBinder _formFileModelBinder;

    public JsonWithFilesFormDataModelBinder(IOptions<MvcJsonOptions> jsonOptions, ILoggerFactory loggerFactory)
    {
        _jsonOptions = jsonOptions;
        _formFileModelBinder = new FormFileModelBinder(loggerFactory);
    }

    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))
                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 successfully 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);
    }
} 

Модель

[ModelBinder(typeof(JsonWithFilesFormDataModelBinder), Name = "data")]
public class Person
{
   public int pId {get; set;}
   public string PName {get; set;}
   public School schoolAttended {get; set;}
   public IFormFile File { get; set; }
}

Запрос почтальона:

enter image description here

...