I'm not being able to post multipart (for file upload) plus raw (for json object) in the same request in Postman.
I have a web api .Net Framework (NOT Core) endpoint to upload a file like the next:
[Route("UploadVideo")]
[HttpPost]
public async Task<HttpResponseMessage> UploadVideo(FileUpload fileUpload)
{
    string videoAllowedExtensions = ConfigurationManager.AppSettings.Get("VideoAllowedExtensions");
    int.TryParse(ConfigurationManager.AppSettings.Get("FileMaxSize"), out int fileMaxSize);
    fileUpload .AllowedExtensions = videoAllowedExtensions;
    fileUpload .MaxSize = fileMaxSize;
    if (fileUpload != null) 
    {
        return await UploadFile(fileUpload);
    }
    return Request.CreateResponse(HttpStatusCode.BadRequest, "No File Attached");
}
public async Task<HttpResponseMessage> UploadFile(FileUpload fileUpload)
{
    Dictionary<short, Tuple<short, string>> filesUploadStatus = new Dictionary<short, Tuple<short, string>>();
    Tuple<short, string> fileUploadStatus;
    short key = 0;
    var httpRequest = HttpContext.Current.Request;
    foreach (string file in httpRequest.Files)
    {
        var postedFile = httpRequest.Files[file];
        if (postedFile != null && postedFile.ContentLength > 0)
        {
            UploadFile uploadFile = new UploadFile
            {
                FileName = postedFile.FileName,
                ContentLength = postedFile.ContentLength,
                ContentType = postedFile.ContentType,
                InputStream = postedFile.InputStream,
                EnterpriseId = fileUpload.EnterpriseId,
                AllowedExtensions = fileUpload.AllowedExtensions,
                MaxSize = fileUpload.MaxSize,
                AzureFolder = fileUpload.AzureFolder
            };
            fileUploadStatus = await CatalogueService.UploadFile(uploadFile);
        }
        else
        {
            var responseMessage = string.Format("Please, upload a file.");
            fileUploadStatus = new Tuple<short, string>((short)ConstantsADM.ResponseStatus.BadRequest, responseMessage);
        }
        filesUploadStatus.Add(key, fileUploadStatus);
        key++;
    }
    HttpStatusCode httpStatudCode = GetStatusCode(filesUploadStatus);
    return Request.CreateResponse(httpStatudCode, filesUploadStatus);
}
private HttpStatusCode GetStatusCode(Dictionary<short, Tuple<short, string>> filesUploadStatus) 
{
    HttpStatusCode response = HttpStatusCode.BadRequest;
    foreach (var dic in filesUploadStatus) 
    {
        short httpResponse = dic.Value.Item1;
        switch (httpResponse)
        {
            case (short)ConstantsADM.ResponseStatus.Created:
                response = HttpStatusCode.Created;
                break;
            case (short)ConstantsADM.ResponseStatus.NotFound:
                response = HttpStatusCode.NotFound;
                break;
        }
    }
    return response;
}
public async Task<Tuple<short, string>> UploadFile(UploadFile uploadFile)
{
    string responseMessage;
    CloudStorageAccount storageAccount = AzureHelper.Connect(uploadFile.EnterpriseId);
    if (storageAccount!=null)
    {
        try
        {
            Tuple<short, string> tup;
            CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
            var shortEnv = ConfigurationManager.AppSettings.Get("AzureStorageContainer");
            var environment = EnvironmentHelpers.GetEnvironment(shortEnv);
            CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(string.Format("{0}{1}", uploadFile.AzureFolder, environment));
            await cloudBlobContainer.CreateIfNotExistsAsync();//TODO: Don't create
            BlobContainerPermissions permissions = new BlobContainerPermissions
            {
                PublicAccess = BlobContainerPublicAccessType.Blob
            };
            await cloudBlobContainer.SetPermissionsAsync(permissions);
            string ext = System.IO.Path.GetExtension(uploadFile.FileName);
            Guid oGUID = Guid.NewGuid();
            string imageName = uploadFile.EnterpriseId.ToString() + "_" + oGUID.ToString() + ext;
            if (uploadFile != null && uploadFile.ContentLength > 0)
            {
                IList<string> AllowedFileExtensions = uploadFile.AllowedExtensions.Split(',');
                var extension = ext.ToLower();
                if (!AllowedFileExtensions.Contains(extension))
                {
                    responseMessage = string.Format("Please Upload file of type {0}", uploadFile.AllowedExtensions);
                    return new Tuple<short, string>((short)ConstantsADM.ResponseStatus.BadRequest, responseMessage);
                }
                else if (uploadFile.ContentLength > uploadFile.MaxSize) // 2048 * 2048 * 1; //Size = 2 MB
                {
                    responseMessage = string.Format("Please Upload a file upto {0} bytes.", uploadFile.MaxSize);
                    return new Tuple<short, string>((short)ConstantsADM.ResponseStatus.BadRequest, responseMessage);
                }
                else
                {
                    CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(imageName);
                    cloudBlockBlob.Properties.ContentType = uploadFile.ContentType;
                    await cloudBlockBlob.UploadFromStreamAsync(uploadFile.InputStream);
                }
                responseMessage = string.Format("Image Updated Successfully.");
                return new Tuple<short, string>((short)ConstantsADM.ResponseStatus.Created, responseMessage);
            }
            responseMessage = string.Format("Please Upload an image.");
            tup = new Tuple<short, string>((short)ConstantsADM.ResponseStatus.NotFound, responseMessage);
            return tup;
        }
        catch (Exception ex)
        {
            responseMessage = ex.InnerException.ToString();
            return new Tuple<short, string>((short)ConstantsADM.ResponseStatus.BadRequest, responseMessage);
        }
    }
    else
    {
        responseMessage = string.Format("Connection was not successful.");
        return new Tuple<short, string>((short)ConstantsADM.ResponseStatus.NotFound, responseMessage);
    }
}
public class FileUpload
{
    public string FileTitle { get; set; }
    public string Description { get; set; }
    public short EnterpriseId { get; set; }
    public int UserId { get; set; }
    public int ApplicationId { get; set; }
    public string AzureFolder { get; set; }
    public string AllowedExtensions { get; set; }
    public int MaxSize { get; set; }
}
OK, this next way is NOT working as fileUpload is received as null or file is received as null depending if I hit SEND from Raw, or from form-data tabs.
[Route("UploadVideo")]
[HttpPost]
public async Task<HttpResponseMessage> UploadVideo(FileUpload fileUpload)
{
    string videoAllowedExtensions = ConfigurationManager.AppSettings.Get("VideoAllowedExtensions");
    int.TryParse(ConfigurationManager.AppSettings.Get("FileMaxSize"), out int fileMaxSize);
    fileUpload .AllowedExtensions = videoAllowedExtensions;
    fileUpload .MaxSize = fileMaxSize;
    if (fileUpload != null) 
    {
        return await UploadFile(fileUpload);
    }
    return Request.CreateResponse(HttpStatusCode.BadRequest, "No File Attached");
}
But this next way it does work as it receives all parameters and the streamed file:
[Route("UploadVideo")]
[HttpPost]
public async Task<HttpResponseMessage> UploadVideo([FromUri] string fileTitle, [FromUri] string description,
                                [FromUri] short enterpriseId, [FromUri] int userId, 
                                [FromUri] int applicationId, [FromUri] string azureFolder) 
{
    string videoAllowedExtensions = ConfigurationManager.AppSettings.Get("VideoAllowedExtensions");
    int.TryParse(ConfigurationManager.AppSettings.Get("FileMaxSize"), out int fileMaxSize);
    FileUpload fileUpload = new FileUpload 
    {
        FileTitle = fileTitle,
        Description = description,
        EnterpriseId = enterpriseId,
        UserId = userId,
        ApplicationId = applicationId,
        AzureFolder = azureFolder,
        AllowedExtensions = videoAllowedExtensions,
        MaxSize = fileMaxSize
    };
    if (fileUpload != null) 
    {
        return await UploadFile(fileUpload);
    }
    return Request.CreateResponse(HttpStatusCode.BadRequest, "No File Attached");
}
WebApi.config.cs
...
config.Formatters.XmlFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data"));
...
I'm expecting to be able to do the request the common -and pretty- way for a post, I mean, receiving a json that will be autommatically mapped to my object.




