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.