Accessing Request.Form.Files throws Exception System.io.InvalidDataException - c#

As mentioned in my Title, upon accessing Request.Form.Files, the application throws the exception
System.Io.InvalidDataException: "Multipart body length limit 16384 exceeded" in an Asp.Net Core 2.0.0 Web Application. The Application I am working on is an Asp.Net Core MVC Web Application. I am using Summernote as my WYSIWYG Text-Editor. There I enabled the Feature to upload Images (s. my Javascript). This worked fine, until I needed to implement another uploader to upload text files like .pdf, txt, doc.
The Error appears while using the summernote texteditor, either with the "standard" upload button or a custom pdf uplader button (s. C# Code). The Image functionality worked fine, until I (tried) to implement the new pdf file uploader. At first my Error looked pretty basic because it was clear, that the files I tried to upload where bigger than 16kb (Asp.Net Cores Uploadlimit), so I tried the "common" methods (s. below) to fix this error, that are found on Stack Overflow and similar sites:
services.Configure<FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue;
x.MultipartBodyLengthLimit = long.MaxValue;
x.MemoryBufferThreshold = 20;
});
or
public class RequestFormSizeLimitAttribute : Attribute, IAuthorizationFilter, IOrderedFilter
{
public int Order { get; }
private readonly FormOptions _formOptions;
public RequestFormSizeLimitAttribute(int valueCountLimit)
{
_formOptions = new FormOptions()
{
ValueCountLimit = valueCountLimit,
KeyLengthLimit = valueCountLimit
};
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var features = context.HttpContext.Features;
var formFeature = features.Get<IFormFeature>();
if (formFeature == null || formFeature.Form == null)
{
// Request form has not been read yet, so set the limits
features.Set(new FormFeature(context.HttpContext.Request, _formOptions));
}
}
}
or
<system.web>
<httpRuntime maxRequestLength="1048576" />
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
however none of these Methods fixed my Error.
First of all my Jquery Code:
//For Image Uploading
function sendFiles(file) {
var data = new FormData();
data.append("file", file);
data.append('divisionId', $('#divisionId').val());
$.ajax({
data: data,
type: "POST",
url: "/api/File/UploadImageAjax",
cache: false,
contentType: false,
processData: false,
success: function (image) {
if (image !== "Error") {
var picture = $(image);
$('#summernote').summernote("insertNode", picture[0]);
} else {
bootbox.alert("Fehler beim hochladen des Bildes.");
}
}
});
}
//For PDF-File Upload
$('#btnUpload').on('click', function (e) {
var validation = validator.form();
e.preventDefault();
if (validation) {
var data = new FormData();
var text = document.getElementById('pdfText').value;
var fileSelect = document.getElementById('pdfFile');
data.append('linkName', text);
data.append('divisionId', $('#divisionId').val());
var files = fileSelect.files;
data.append('file', files[0]);
closeModal();
$.ajax({
data: data,
type: "POST",
url: "/api/File/UploadTextFileAjax",
cache: false,
contentType: false,
processData: false,
success: function (file) {
var atag = document.createElement('a');
atag.setAttribute('href', file.absoulutePath);
atag.setAttribute('id', file.fileId);
atag.innerHtml = file.linkText;
$('#summernote').summernote('insertNode', atag);
},
error: function(respons) {
bootbox.alert("Fehler beim Speichern der Text Datei.");
}
});
}
});
And finally my C# Code from the Controller:
[HttpPost]
[RequestFormSizeLimit(valueCountLimit: 2147483647)]
public async Task<IActionResult> UploadImageAjax()
{
//Exception thrown here.
var files = Request.Form.Files;
var request = Request.Form.FirstOrDefault(d => d.Key == "divisionId");
var divisionName = await GetDivisionNameAsync(request);
if (divisionName != null)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
if (files.Count == 1 && user != null)
{
for (int i = 0; i < 1; i++)
{
var file = files[i];
if (TestImageFileName(file))
{
var path = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.ToString().Trim('"');
var fileName = $#"\images\Sportarten\{divisionName}\{path}";
if (!await _imageHandler.IsImageInDbAsync(fileName))
{
path = _hosting.WebRootPath + fileName;
using (FileStream fs = System.IO.File.Create(path))
{
await file.CopyToAsync(fs);
await fs.FlushAsync();
}
var image = new ImageViewModel { FileName = file.FileName, AbsolutePath = fileName, AspNetUserId = user.Id, FullPath = path };
var imageId = await _imageHandler.AddImageAsync(image);
var imageNode = $#"<img id='{imageId}' src='{fileName}' class='img-responsive'/>";
return Json(imageNode);
}
var id = await _imageHandler.GetImageIdbyNameAsync(path);
var node = $#"<img id='{id}' src='{fileName}' class='img-responsive'/>";
return Json(node);
}
}
}
}
return BadRequest("Error");
}
[HttpPost]
public async Task<IActionResult> UploadTextFileAjax()
{
//Exception thrown here.
var files = Request.Form.Files;
var request = Request.Form.FirstOrDefault(d => d.Key == "divisionId");
var divisionName = await GetDivisionNameAsync(request);
var linkText = Request.Form.FirstOrDefault(l => l.Key == "linkName").Value.ToString();
if (linkText != null && divisionName != null)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
if (files.Count == 1 && user != null)
{
for (int i = 0; i < 1; i++)
{
var file = files[i];
if (TestTextFileName(file))
{
var path = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.ToString().Trim('"');
var fileName = $#"\files\Sportarten\{divisionName}\{path}";
if (await _file.IsFileInDb(fileName))
{
path = _hosting.WebRootPath + fileName;
using (FileStream fs = System.IO.File.Create(path))
{
await file.CopyToAsync(fs);
await fs.FlushAsync();
}
var textFile = new FileViewModel
{
AbsolutePath = fileName,
AspNetUserId = user.Id,
FileName = file.FileName,
FullPath = path
};
var fileId = await _file.AddFile(textFile);
return Ok(new {absolutePath = path, fileId = fileId, linkText = linkText});
}
var oldText = await _file.FindFilebyName(path);
return Ok(new { absolutePath = oldText.AbsolutePath, fileId = oldText.FileId, linkText = linkText });
}
}
}
}
return BadRequest("Error");
}
At last here is my Stacktrace I get, when the error is thrown(sorry for the bad quality):
Full Stacktrace of Error

Related

Unable to store filesize data in Azure Media Service Assets

Currently building a web api for the existing web-based media services to encode uploaded videos.
The goal of my solution is to create a api call where i'll be sending the mp4 link and do the processing (encoding and streaming of the given mp4 link). I was able to fetch the mp4 and download to the server and reupload to its own blob storage. However if I check the AMS explorer, every parameters I passed exists except for the filesize. Here's my WEB API call I created (a total replicate of the existing media service form method. (https://tiltestingstreaming.azurewebsites.net/
)
[HttpPost]
public JsonResult UploadApi(String video_url)
{
var id = 1;
WebClient client = new WebClient();
var videoStream = new MemoryStream(client.DownloadData(video_url));
var container = CloudStorageAccount.Parse(mediaServiceStorageConnectionString).CreateCloudBlobClient().GetContainerReference(mediaServiceStorageContainerReference);
container.CreateIfNotExists();
var fileName = Path.GetFileName(video_url);
var fileToUpload = new CloudFile()
{
BlockCount = 1,
FileName = fileName,
Size = videoStream.Length,
BlockBlob = container.GetBlockBlobReference(fileName),
StartTime = DateTime.Now,
IsUploadCompleted = false,
UploadStatusMessage = string.Empty
};
Session.Add("CurrentFile", fileToUpload);
byte[] chunk = new byte[videoStream.Length];
//request.InputStream.Read(chunk, 0, Convert.ToInt32(request.Length));
//JsonResult returnData = null;
string fileSession = "CurrentFile";
CloudFile model = (CloudFile)Session[fileSession];
var blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(
string.Format(CultureInfo.InvariantCulture, "{0:D4}", id)));
try
{
model.BlockBlob.PutBlock(
blockId,
videoStream, null, null,
new BlobRequestOptions()
{
RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(10), 3)
},
null);
}
catch (StorageException e)
{
model.IsUploadCompleted = true;
model.UploadStatusMessage = "Failed to Upload file. Exception - " + e.Message;
return Json(new { error = true, isLastBlock = false, message = model.UploadStatusMessage });
}
var blockList = Enumerable.Range(1, (int)model.BlockCount).ToList<int>().ConvertAll(rangeElement => Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0:D4}", rangeElement))));
model.BlockBlob.PutBlockList(blockList);
var duration = DateTime.Now - model.StartTime;
float fileSizeInKb = model.Size / 1024;
string fileSizeMessage = fileSizeInKb > 1024 ? string.Concat((fileSizeInKb / 1024).ToString(CultureInfo.CurrentCulture), " MB") : string.Concat(fileSizeInKb.ToString(CultureInfo.CurrentCulture), " KB");
model.UploadStatusMessage = string.Format(CultureInfo.CurrentCulture, "File of size {0} took {1} seconds to upload.", fileSizeMessage, duration.TotalSeconds);
IAsset mediaServiceAsset = CreateMediaAsset(model);
model.AssetId = mediaServiceAsset.Id;
//if (id == model.BlockCount){CommitAllChunks(model);}
return Json(new { error = false, isLastBlock = false, message = string.Empty, filename = fileName,filesize = videoStream.Length });
}
Functions used on the form-method solution.
[HttpPost]
public ActionResult SetMetadata(int blocksCount, string fileName, long fileSize)
{
var container = CloudStorageAccount.Parse(mediaServiceStorageConnectionString).CreateCloudBlobClient().GetContainerReference(mediaServiceStorageContainerReference);
container.CreateIfNotExists();
var fileToUpload = new CloudFile()
{
BlockCount = blocksCount,
FileName = fileName,
Size = fileSize,
BlockBlob = container.GetBlockBlobReference(fileName),
StartTime = DateTime.Now,
IsUploadCompleted = false,
UploadStatusMessage = string.Empty
};
Session.Add("CurrentFile", fileToUpload);
return Json(true);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult UploadChunk(int id)
{
HttpPostedFileBase request = Request.Files["Slice"];
byte[] chunk = new byte[request.ContentLength];
request.InputStream.Read(chunk, 0, Convert.ToInt32(request.ContentLength));
JsonResult returnData = null;
string fileSession = "CurrentFile";
if (Session[fileSession] != null)
{
CloudFile model = (CloudFile)Session[fileSession];
returnData = UploadCurrentChunk(model, chunk, id);
if (returnData != null)
{
return returnData;
}
if (id == model.BlockCount)
{
return CommitAllChunks(model);
}
}
else
{
returnData = Json(new
{
error = true,
isLastBlock = false,
message = string.Format(CultureInfo.CurrentCulture, "Failed to Upload file.", "Session Timed out")
});
return returnData;
}
return Json(new { error = false, isLastBlock = false, message = string.Empty });
}
private JsonResult UploadCurrentChunk(CloudFile model, byte[] chunk, int id)
{
using (var chunkStream = new MemoryStream(chunk))
{
var blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(
string.Format(CultureInfo.InvariantCulture, "{0:D4}", id)));
try
{
model.BlockBlob.PutBlock(
blockId,
chunkStream, null, null,
new BlobRequestOptions()
{
RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(10), 3)
},
null);
return null;
}
catch (StorageException e)
{
model.IsUploadCompleted = true;
model.UploadStatusMessage = "Failed to Upload file. Exception - " + e.Message;
return Json(new { error = true, isLastBlock = false, message = model.UploadStatusMessage });
}
}
}
private ActionResult CommitAllChunks(CloudFile model)
{
model.IsUploadCompleted = true;
bool errorInOperation = false;
try
{
var blockList = Enumerable.Range(1, (int)model.BlockCount).ToList<int>().ConvertAll(rangeElement => Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0:D4}", rangeElement))));
model.BlockBlob.PutBlockList(blockList);
var duration = DateTime.Now - model.StartTime;
float fileSizeInKb = model.Size / 1024;
string fileSizeMessage = fileSizeInKb > 1024 ? string.Concat((fileSizeInKb / 1024).ToString(CultureInfo.CurrentCulture), " MB") : string.Concat(fileSizeInKb.ToString(CultureInfo.CurrentCulture), " KB");
model.UploadStatusMessage = string.Format(CultureInfo.CurrentCulture, "File of size {0} took {1} seconds to upload.", fileSizeMessage, duration.TotalSeconds);
IAsset mediaServiceAsset = CreateMediaAsset(model);
model.AssetId = mediaServiceAsset.Id;
}
catch (StorageException e)
{
model.UploadStatusMessage = "Failed to upload file. Exception - " + e.Message;
errorInOperation = true;
}
return Json(new
{
error = errorInOperation,
isLastBlock = model.IsUploadCompleted,
message = model.UploadStatusMessage,
assetId = model.AssetId
});
}
private IAsset CreateMediaAsset(CloudFile model)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(mediaServiceStorageConnectionString);
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer mediaBlobContainer = cloudBlobClient.GetContainerReference(mediaServiceStorageContainerReference);
mediaBlobContainer.CreateIfNotExists();
// Create a new asset.
IAsset asset = context.Assets.Create("UploadedVideo-" + Guid.NewGuid().ToString().ToLower(), AssetCreationOptions.None);
IAccessPolicy writePolicy = context.AccessPolicies.Create("writePolicy", TimeSpan.FromMinutes(120), AccessPermissions.Write);
ILocator destinationLocator = context.Locators.CreateLocator(LocatorType.Sas, asset, writePolicy);
// Get the asset container URI and copy blobs from mediaContainer to assetContainer.
Uri uploadUri = new Uri(destinationLocator.Path);
string assetContainerName = uploadUri.Segments[1];
CloudBlobContainer assetContainer = cloudBlobClient.GetContainerReference(assetContainerName);
string fileName = HttpUtility.UrlDecode(Path.GetFileName(model.BlockBlob.Uri.AbsoluteUri));
var sourceCloudBlob = mediaBlobContainer.GetBlockBlobReference(fileName);
sourceCloudBlob.FetchAttributes();
if (sourceCloudBlob.Properties.Length > 0)
{
IAssetFile assetFile = asset.AssetFiles.Create(fileName);
var destinationBlob = assetContainer.GetBlockBlobReference(fileName);
destinationBlob.DeleteIfExists();
destinationBlob.StartCopy(sourceCloudBlob);
destinationBlob.FetchAttributes();
if (sourceCloudBlob.Properties.Length != destinationBlob.Properties.Length)
model.UploadStatusMessage += "Failed to copy as Media Asset!";
}
destinationLocator.Delete();
writePolicy.Delete();
sourceCloudBlob.Delete(); //delete temp blob
// Refresh the asset.
asset = context.Assets.Where(a => a.Id == asset.Id).FirstOrDefault();
var ismAssetFiles = asset.AssetFiles.FirstOrDefault();
ismAssetFiles.IsPrimary = true;
ismAssetFiles.Update();
model.UploadStatusMessage += " Media file uploaded successfully by id: " + asset.Id;
model.AssetId = asset.Id;
return asset;
}
[HttpPost]
public ActionResult EncodeToAdaptiveBitrateMP4s(string assetId)
{
// Note: You need atleast 1 reserve streaming unit for dynamic packaging of encoded media. If you don't have that, you can't see video file playing.
IAsset inputAsset = GetAssetById(assetId);
string token = string.Empty;
string uploadFileOriginalName = string.Empty;
////// Without preset (say default preset), works very well
//IJob job = context.Jobs.CreateWithSingleTask(MediaProcessorNames.AzureMediaEncoder,
// MediaEncoderTaskPresetStrings.H264AdaptiveBitrateMP4Set720p,
// inputAsset,
// "UploadedVideo-" + Guid.NewGuid().ToString().ToLower() + "-Adaptive-Bitrate-MP4",
// AssetCreationOptions.None);
//job.Submit();
//IAsset encodedOutputAsset = job.OutputMediaAssets[0];
//// XML Preset
IJob job = context.Jobs.Create(inputAsset.Name);
IMediaProcessor processor = GetLatestMediaProcessorByName("Media Encoder Standard");
string configuration = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/MediaServicesCustomPreset.xml"));
ITask task = job.Tasks.AddNew(inputAsset.Name + "- encoding task", processor, configuration, TaskOptions.None);
task.InputAssets.Add(inputAsset);
task.OutputAssets.AddNew(inputAsset.Name + "-Adaptive-Bitrate-MP4", AssetCreationOptions.None);
job.Submit();
IAsset encodedAsset = job.OutputMediaAssets[0];
// process policy & encryption
ProcessPolicyAndEncryption(encodedAsset);
// Get file name
string fileSession = "CurrentFile";
if (Session[fileSession] != null)
{
CloudFile model = (CloudFile)Session[fileSession];
uploadFileOriginalName = model.FileName;
}
// Generate Streaming URL
string smoothStreamingUri = GetStreamingOriginLocator(encodedAsset, uploadFileOriginalName);
// add jobid and output asset id in database
AzureMediaServicesContext db = new AzureMediaServicesContext();
var video = new Video();
video.RowAssetId = assetId;
video.EncodingJobId = job.Id;
video.EncodedAssetId = encodedAsset.Id;
video.LocatorUri = smoothStreamingUri;
video.IsEncrypted = useAESRestriction;
db.Videos.Add(video);
db.SaveChanges();
if (useAESRestriction)
{
token = AzureMediaAsset.GetTestToken(encodedAsset.Id, encodedAsset);
}
// Remove session
Session.Remove("CurrentFile");
// return success response
return Json(new
{
error = false,
message = "Congratulations! Video is uploaded and pipelined for encoding, check console log for after encoding playback details.",
assetId = assetId,
jobId = job.Id,
locator = smoothStreamingUri,
encrypted = useAESRestriction,
token = token
});
}
The actual challenge that I encounter was, I'm not sure why the filesize of the downloaded remote mp4 file doesn't store in the media services asset file yet I was able to return the value via the json response of the my api call. Please check attached Screenshot of the API response.
Was able to figure out my own problem. All I need to do is to copy the function of my encoding function that was bind to an ActionResult data type. I think ActionResult is part of the form-method solution and I am building a WebAPI call solution of the working form-method.
From the original call function
[HttpPost] public ActionResult EncodeToAdaptiveBitrateMP4s(string assetId)
I copy the entire function into my WebApi Call function, like this:
[HttpPost]
public JsonResult UploadApi(String video_url)
{
var id = 1;
WebClient client = new WebClient();
var videoStream = new MemoryStream(client.DownloadData(video_url));
var container = CloudStorageAccount.Parse(mediaServiceStorageConnectionString).CreateCloudBlobClient().GetContainerReference(mediaServiceStorageContainerReference);
container.CreateIfNotExists();
var fileName = Path.GetFileName(video_url);
var fileToUpload = new CloudFile()
{
BlockCount = 1,
FileName = fileName,
Size = videoStream.Length,
BlockBlob = container.GetBlockBlobReference(fileName),
StartTime = DateTime.Now,
IsUploadCompleted = false,
UploadStatusMessage = string.Empty
};
Session.Add("CurrentFile", fileToUpload);
byte[] chunk = new byte[videoStream.Length];
//request.InputStream.Read(chunk, 0, Convert.ToInt32(request.Length));
//JsonResult returnData = null;
string fileSession = "CurrentFile";
CloudFile model = (CloudFile)Session[fileSession];
var blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(
string.Format(CultureInfo.InvariantCulture, "{0:D4}", id)));
try
{
model.BlockBlob.PutBlock(
blockId,
videoStream, null, null,
new BlobRequestOptions()
{
RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(10), 3)
},
null);
}
catch (StorageException e)
{
model.IsUploadCompleted = true;
model.UploadStatusMessage = "Failed to Upload file. Exception - " + e.Message;
return Json(new { error = true, isLastBlock = false, message = model.UploadStatusMessage });
}
var blockList = Enumerable.Range(1, (int)model.BlockCount).ToList<int>().ConvertAll(rangeElement => Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0:D4}", rangeElement))));
model.BlockBlob.PutBlockList(blockList);
var duration = DateTime.Now - model.StartTime;
float fileSizeInKb = model.Size / 1024;
string fileSizeMessage = fileSizeInKb > 1024 ? string.Concat((fileSizeInKb / 1024).ToString(CultureInfo.CurrentCulture), " MB") : string.Concat(fileSizeInKb.ToString(CultureInfo.CurrentCulture), " KB");
model.UploadStatusMessage = string.Format(CultureInfo.CurrentCulture, "File of size {0} took {1} seconds to upload.", fileSizeMessage, duration.TotalSeconds);
IAsset mediaServiceAsset = CreateMediaAsset(model);
model.AssetId = mediaServiceAsset.Id;
// Note: You need atleast 1 reserve streaming unit for dynamic packaging of encoded media. If you don't have that, you can't see video file playing.
var assetId = model.AssetId;
IAsset inputAsset = GetAssetById(assetId);
string token = string.Empty;
string uploadFileOriginalName = string.Empty;
////// Without preset (say default preset), works very well
//IJob job = context.Jobs.CreateWithSingleTask(MediaProcessorNames.AzureMediaEncoder,
// MediaEncoderTaskPresetStrings.H264AdaptiveBitrateMP4Set720p,
// inputAsset,
// "UploadedVideo-" + Guid.NewGuid().ToString().ToLower() + "-Adaptive-Bitrate-MP4",
// AssetCreationOptions.None);
//job.Submit();
//IAsset encodedOutputAsset = job.OutputMediaAssets[0];
//// XML Preset
IJob job = context.Jobs.Create(inputAsset.Name);
IMediaProcessor processor = GetLatestMediaProcessorByName("Media Encoder Standard");
string configuration = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/MediaServicesCustomPreset.xml"));
ITask task = job.Tasks.AddNew(inputAsset.Name + "- encoding task", processor, configuration, TaskOptions.None);
task.InputAssets.Add(inputAsset);
task.OutputAssets.AddNew(inputAsset.Name + "-Adaptive-Bitrate-MP4", AssetCreationOptions.None);
job.Submit();
IAsset encodedAsset = job.OutputMediaAssets[0];
// process policy & encryption
ProcessPolicyAndEncryption(encodedAsset);
// Get file name
uploadFileOriginalName = model.FileName;
// Generate Streaming URL
string smoothStreamingUri = GetStreamingOriginLocator(encodedAsset, uploadFileOriginalName);
// add jobid and output asset id in database
AzureMediaServicesContext db = new AzureMediaServicesContext();
var video = new Video();
video.RowAssetId = assetId;
video.EncodingJobId = job.Id;
video.EncodedAssetId = encodedAsset.Id;
video.LocatorUri = smoothStreamingUri;
video.IsEncrypted = useAESRestriction;
db.Videos.Add(video);
db.SaveChanges();
if (useAESRestriction)
{
token = AzureMediaAsset.GetTestToken(encodedAsset.Id, encodedAsset);
}
// Remove session
Session.Remove("CurrentFile");
// return success response
return Json(new
{
error = false,
message = "Congratulations! Video is uploaded and pipelined for encoding, check console log for after encoding playback details.",
assetId = assetId,
jobId = job.Id,
locator = smoothStreamingUri,
encrypted = useAESRestriction,
token = token
});
//if (id == model.BlockCount){CommitAllChunks(model);}
//return Json(new { error = false, isLastBlock = false, message = string.Empty, filename = fileName,filesize = videoStream.Length });
}
However this kind of solution is to rigid and not for a long term solution but the concept was there and able to meet my goal. I will just redo my code and re-create a more flexible solution.
NOTE: I am not a C# developer. Respect for the beginner like me.

Issue with form-data name

I have an angular application that is uploading files using my API.
I have a bit of code that looks like this:
var url = __env.apiUrl + 'documents/' + containerName + '/' + reference;
var formData = new FormData();
var request = {
method: 'POST',
url: url,
data: formData,
headers: {
'Content-Type': undefined
}
};
formData.append('file', file);
formData.append('metadata', JSON.stringify(metadata));
return $http(request).then(function (response) {
SimpleCache.remove(__env.apiUrl + '/documents');
listDirectiveService.refresh('document');
ngNotify.set('Your document was created.');
}, notifications.handleError).finally(function () {
onComplete();
});
On my API side, the c# used to get the file looks like this:
if (!request.Content.IsMimeMultipartContent("form-data")) throw new HttpResponseException(request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
Valiate(containerName, directoryName);
var filesReadToProvider = await request.Content.ReadAsMultipartAsync();
// We assume that the form data name is file and metadata respectively
var fileStream = filesReadToProvider.Contents.SingleOrDefault(m => m.Headers.ContentDisposition.Name.Equals("\"file\"", StringComparison.OrdinalIgnoreCase));
var metaDataStream = filesReadToProvider.Contents.SingleOrDefault(m => m.Headers.ContentDisposition.Name.Equals("\"metadata\"", StringComparison.OrdinalIgnoreCase));
if (fileStream == null) throw new ArgumentNullException(nameof(fileStream));
if (metaDataStream == null) throw new ArgumentNullException(nameof(metaDataStream));
This works, but the problem is the name of the ContentDisposition.
If you notice, it looks for "file" instead of file.
Does anyone know why it has the extra quotes?
I never found out why this was happening, so I just made my function like this:
public async Task<string> CreateAsync(HttpRequestMessage request, string containerName, string directoryName, string existingUrl = "")
{
if (!request.Content.IsMimeMultipartContent("form-data")) throw new HttpResponseException(request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
Valiate(containerName, directoryName);
var filesReadToProvider = await request.Content.ReadAsMultipartAsync();
// We assume that the form data name is file and metadata respectively
var fileStream = filesReadToProvider.Contents.SingleOrDefault(m =>
m.Headers.ContentDisposition.Name.Equals("\"file\"", StringComparison.OrdinalIgnoreCase) ||
m.Headers.ContentDisposition.Name.Equals("file", StringComparison.OrdinalIgnoreCase));
var metaDataStream = filesReadToProvider.Contents.SingleOrDefault(m =>
m.Headers.ContentDisposition.Name.Equals("\"metadata\"", StringComparison.OrdinalIgnoreCase) ||
m.Headers.ContentDisposition.Name.Equals("metadata", StringComparison.OrdinalIgnoreCase));
if (fileStream == null) throw new ArgumentNullException(nameof(fileStream));
if (metaDataStream == null) throw new ArgumentNullException(nameof(metaDataStream));
// Upload our file
var fileBytes = await fileStream.ReadAsByteArrayAsync();
var mediaType = fileStream.Headers.ContentType.MediaType;
var friendlyFileName = fileStream.Headers.ContentDisposition.FileName.Replace("\"", string.Empty);
var fileName = $"{Guid.NewGuid()}{Path.GetExtension(friendlyFileName)}";
var directory = GetDirectory(containerName, directoryName);
var fileUrl = await Upload(directory, fileName, mediaType, fileBytes);
// Add our metadata
var metadata = await GetMetadataFromMemoryStreamAsync(metaDataStream);
metadata.Add("fileName", friendlyFileName);
metadata.Add("directory", directoryName);
metadata.Add("created", DateTime.UtcNow.ToString(CultureInfo.InvariantCulture));
await AddFileMetaDataAsync(fileUrl, metadata);
// Delete any existing file
if (!string.IsNullOrEmpty(existingUrl) && fileUrl != existingUrl) await DeleteAsync(containerName, directoryName, existingUrl);
return fileUrl;
}
Just to cover all bases. It isn't the best, but it should work fine.

OpenXML not creating document on production, but fine in Dev

I have launched a new application at work. We create letters using OpenXML which works flawlessly on Dev, but on production the solution is not returning.
$("#createLetter").on("click", CreateLetter);
function CreateLetter() {
$.ajax({
type: "POST",
url: "/Letters/CreateLetter",
data: {
EntityType: "#overview.EntityType",
EntityId: #overview.EntityId,
Recipient: $("#Recipient").val(),
TemplatesLocation: $("#templatePath").val(),
SaveAs: $("#saveAs").val()
},
async: false,
success: openLetter
});
}
function openLetter(data) {
openFile(data);
window.location.reload(false);
}
Controller Method:
[ValidateInput(false)]
[HttpPost]
public JsonResult CreateLetter(CreateLetter input)
{
Recipient obj = logic.SplitRecipientInput(input.Recipient);
input.RecipientId = obj.RecipientId;
input.RecipientType = obj.Type;
input.Username = Helpers.GetLoggedInUser();
var x = logic.CreateLetter(input);
if (x.Success == 1)
{
return Json(x.Data, JsonRequestBehavior.AllowGet);
}
else
{
return Json("Error", JsonRequestBehavior.AllowGet);
}
}
Consumption Logic:
public CreatedLetter CreateLetter(CreateLetter input)
{
CreatedLetter response = new CreatedLetter();
Parameters.Add("TemplatePath", GetApiValue(input.TemplatesLocation));
Parameters.Add("EntityType", GetApiValue(input.EntityType));
Parameters.Add("EntityId", GetApiValue(input.EntityId));
Parameters.Add("RecipientId", GetApiValue(input.RecipientId));
Parameters.Add("RecipientType", GetApiValue(input.RecipientType));
Parameters.Add("Username", GetApiValue(input.Username));
Parameters.Add("SaveAs", GetApiValue(input.SaveAs));
response = Api.WebRequest<CreatedLetter>("CreateLetters", Parameters, Method.POST) as CreatedLetter;
return response;
}
API Controller method:
[ActionName("CreateLetter")]
[HttpPost]
public ApiResponse CreateLetter(LetterCreateInput input)
{
try
{
LetterTemplateLogic logic = new LetterTemplateLogic();
Random r = new Random();
var randomId = r.Next(100000, 999999);
string fileName = string.Format("{0} - {1}", randomId, input.SaveAs);
input.SaveAs = fileName;
// Get all objects for Letter
List<object> objs = logic.TemplateObjectsRetriever(input.EntityId, input.EntityType, input.Username, randomId);
objs.Add(logic.GetRecipient(input.RecipientId, input.RecipientType));
// Get save location
string saveLocation = logic.LetterLocationResolver(input.EntityId, input.EntityType);
var data = logic.OpenAndUpdateTemplate(objs, input.TemplatePath, input.SaveAs, saveLocation, FileExtension);
AttachmentInput letterAttachment = new AttachmentInput();
letterAttachment.Id = input.EntityId;
letterAttachment.FileTypeId = 1;
letterAttachment.Path = data;
letterAttachment.Username = input.Username;
letterAttachment.Description = fileName;
letterAttachment.EntityType = input.EntityType;
logic.InsertLetterAttachment(letterAttachment);
return ApiResponse.Return(data);
}
catch (Exception ex)
{
return ApiResponse.Error(ex);
}
}
This returns literally nothing on production. No errors in the console, no errors from the API which logs erroneous calls. I was hoping someone could make a suggestion?
Thanks.

File Upload in Asp.net core 2.0 issue creating 0 byte Image

I, am using angular 5, with asp.net core 2.0. I, am trying to upload the file to the server. The code update the file to the server. But with 0 kb of data and sometime it upload the file.
The file size is not large. Its in KB.
Here is the Angular code
public QuestionPostHttpCall(_questionPhotoVM: QuestionPhotoViewModel): Observable<GenericResponseObject<QuestionPhotoViewModel[]>> {
const formData: FormData = new FormData();
formData.append('FileUpload', _questionPhotoVM.FileUpload);
formData.append('QuestionText', _questionPhotoVM.questionText);
formData.append('QuestionId', _questionPhotoVM.questionId);
const headers = new HttpHeaders().set('enctype', 'multipart/form-data');
return this._httpClientModule.post<GenericResponseObject<QuestionPhotoViewModel[]>>(this.questionPhotoUrl, formData);
}
In the controller I, can receive the file.
Here is the controller method
[HttpPost]
public JsonResult QuestionPhotoPost(IFormFile FileUpload, string QuestionText, Guid? QuestionId)
{
string TempFileName = string.Empty;
var directiveToUpload = Path.Combine(_environment.WebRootPath, "images\\UploadFile");
var http = HttpRequestExtensions.GetUri(Request);
QuestionViewModel model = new QuestionViewModel();
try
{
if (FileUpload != null)
{
TempFileName = FileUpload.FileName;
CheckFileFromFrontEnd();
}
}
catch (Exception exception)
{
}
void CheckFileFromFrontEnd()
{
if (FileUpload != null)
{
if (!System.IO.Directory.Exists(directiveToUpload))
{
System.IO.Directory.CreateDirectory(directiveToUpload);
}
if (System.IO.File.Exists(string.Format("{0}\\{1}\\{2}", _environment.WebRootPath, "images\\UploadFile", FileUpload.FileName)))
{
TempFileName = Guid.NewGuid().ToString() + FileUpload.FileName;
}
model.PictureUrl = string.Format("{0}://{1}/{2}/{3}/{4}", http.Scheme, http.Authority, "images", "UploadFile", TempFileName);
SaveFileToServer(TempFileName);
}
}
void SaveFileToServer(string FileName)
{
if (FileUpload.Length > 0)
{
using (var stream = new FileStream(Path.Combine(directiveToUpload, FileName), FileMode.Create))
{
FileUpload.CopyToAsync(stream);
}
}
}
return Json(genericResponseObject);
}
The file is uploaded to the server. But some time it upload with 0 byte and sometime it upload correctly.
The resolution of file is 570 X 400 and size of file 197KB
Where I, am doing wrong?? Please anyone let me know. Do, I need to specify max byte in somewhere ??
Your problem is that you are using an asynchronous function and not awaiting it.
You are using ASP.NET Core so you should (read "must") use the async-all-the-way pattern:
[HttpPost]
public async Task<JsonResult> QuestionPhotoPost(IFormFile FileUpload, string QuestionText, Guid? QuestionId)
{
string TempFileName = string.Empty;
var directiveToUpload = Path.Combine(_environment.WebRootPath, "images\\UploadFile");
var http = HttpRequestExtensions.GetUri(Request);
QuestionViewModel model = new QuestionViewModel();
try
{
if (FileUpload != null)
{
TempFileName = FileUpload.FileName;
await CheckFileFromFrontEndAsync();
}
}
catch (Exception exception)
{
}
async Task CheckFileFromFrontEndsync()
{
if (FileUpload != null)
{
if (!System.IO.Directory.Exists(directiveToUpload))
{
System.IO.Directory.CreateDirectory(directiveToUpload);
}
if (System.IO.File.Exists(string.Format("{0}\\{1}\\{2}", _environment.WebRootPath, "images\\UploadFile", FileUpload.FileName)))
{
TempFileName = Guid.NewGuid().ToString() + FileUpload.FileName;
}
model.PictureUrl = string.Format("{0}://{1}/{2}/{3}/{4}", http.Scheme, http.Authority, "images", "UploadFile", TempFileName);
await SaveFileToServerAsync(TempFileName);
}
}
async Task SaveFileToServerAsync(string FileName)
{
if (FileUpload.Length > 0)
{
using (var stream = new FileStream(Path.Combine(directiveToUpload, FileName), FileMode.Create))
{
await FileUpload.CopyToAsync(stream);
}
}
}
return Json(genericResponseObject);
}
To make the code more readable, I'd move those inline functions to outside, though.

jQuery Ajax failing to call to Controller Action Result when deployed to server

In my MVC 4, the code below is not calling controller action when deployed to the server. but it is working on my local.
I am using IE 7.
THANKS IN ADVANCE.
js code:
$("#button").click(function () {
var uploadFile = document.getElementById("myFile").value;
var fullPath = document.getElementById('myFile').value;
var urlRegisterPartner = $('#registerurl').data('register-url');
if (fullPath) {
var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
var filename = fullPath.substring(startIndex);
if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
filename = filename.substring(1);
}
$("#myModal").dialog("open");
$.get(urlRegisterPartner, { uploadFile: uploadFile }, function (data) {
alert(data.Messages);
$("#myModal").dialog("close");
});
}
else {
alert('Please select file to upload');
}
});
actionresult:
[HttpGet]
public JsonResult Upload(string uploadFile)
{
Message msg = new Message();
string fileLocation = Server.MapPath("~/UploadedFile/") + Path.GetFileName(uploadFile);
msg.Messages = uploadRepo.ReadFile(uploadFile, fileLocation);
return Json(msg, JsonRequestBehavior.AllowGet);
}

Categories

Resources