My application is allowing me to upload the document files(mandatory field) in the form. In Database, we are having the column 'Documents' which stores the uploaded file path. Sometimes for some users, the user is filling the form and when they click on the save button data inserted successfully but with the null value in the 'Documents' column, also no files uploaded in the upload file path. From the frontend, I am validating(Required field) the Document upload field but still, a null value is going to the Database also not throwing any exceptions in the log files.
Is there any way to catch the exception regarding this?
'SubmitController.cs'
[HttpPost]
[Route("Add")]
public string AddRecord([FromBody]ProductionUpload data)
{
string recaptcha = string.Empty;
try
{
'Validate the model'
if (!ModelState.IsValid)
{
throw new Exception("Server-side validation message(s): " +
ModelState.Values.Select(v => v.Errors.Select(e => e.ErrorMessage).Aggregate((a, b) => a + "; " + b))
.Aggregate((a, b) => a + "; " + b));
}
'Validate Recaptcha response'
if (!ValidateRecaptchaResponse(data.Recaptcha))
{
throw new Exception("Invalid Recaptcha response: " + data.Recaptcha);
}
'Save the request to DB'
data.DateOfSubmission = DateTime.UtcNow;
_context.ProductionUploads.Add(data);
_context.SaveChanges();
data.RegistryNumber = "P" + data.Id.ToString().PadLeft(6, '0');
_context.SaveChanges();
recaptcha = data.Recaptcha;
}
catch (Exception ex)
{
SendExceptionEmail(ex);
_logger.LogError("{0}\n{1}", ex.Message, ex.StackTrace);
throw;
}
return recaptcha;
}
[HttpPost]
[DisableRequestSizeLimit]
[Route("Upload")]
public void UploadDocument()
{
List<ProductionUpload> fileData = new List<ProductionUpload>();
try
{
var recaptcha = Request.Form["data"].ToString();
var files = Request.Form.Files;
// Validate the document
if (files.Count > 0)
{
uint maximumDocumentSize = _configuration.GetSection("AppSettings").GetValue<uint>("MaximumDocumentSize");
List<FileType> allowedDocumentTypes = _configuration.GetSection("AppSettings:AllowedDocumentTypes").Get<List<FileType>>();
var fileExt = Path.GetExtension(files[0].FileName);
if (files[0].Length == 0 || files[0].Length > maximumDocumentSize ||
(!allowedDocumentTypes.Any(ft => ft.Extension.ToLower() == fileExt.ToLower() && (string.IsNullOrEmpty(ft.ContentType) || ft.ContentType.ToLower() == files[0].ContentType.ToLower()))))
{
throw new Exception(string.Format("Server-side file validation failure: {0}, {1} bytes, {2} content type", files[0].FileName, files[0].Length, files[0].ContentType));
}
}
'Validate the cover letter
if (files.Count > 1)
{
uint maximumCoverLetterSize = _configuration.GetSection("AppSettings").GetValue<uint>("MaximumCoverLetterSize");
List<FileType> allowedCoverLetterTypes = _configuration.GetSection("AppSettings:AllowedCoverLetterTypes").Get<List<FileType>>();
var fileExt = Path.GetExtension(files[1].FileName);
if (files[1].Length == 0 || files[1].Length > maximumCoverLetterSize ||
(!allowedCoverLetterTypes.Any(ft => ft.Extension.ToLower() == fileExt.ToLower() && (string.IsNullOrEmpty(ft.ContentType) || ft.ContentType.ToLower() == files[1].ContentType.ToLower()))))
{
throw new Exception(string.Format("Server-side file validation failure: {0}, {1} bytes, {2} content type", files[1].FileName, files[1].Length, files[1].ContentType));
}
}
'Get the previously saved Submission from the database'
ProductionUpload productionUpload = _context.ProductionUploads.SingleOrDefault(sr => sr.Recaptcha == recaptcha);
if (productionUpload == null || productionUpload.Id == 0)
{
throw new Exception("Invalid Recaptcha response: " + recaptcha);
}
'Save the uploaded files'
string fileUploadPath = _configuration.GetSection("AppSettings").GetValue<string>("FileUploadPath");
string pathToSave = Path.Combine(fileUploadPath, Guid.NewGuid().ToString());
if (!Directory.Exists(pathToSave))
Directory.CreateDirectory(pathToSave);
for (int i = 0; i < files.Count; i++)
{
var fileName = Path.GetFileName(files[i].FileName);
var localFileName = ReplaceInvalidCharacters(fileName);
var dbPath = Path.Combine(pathToSave, localFileName);
using (var stream = new FileStream(dbPath, FileMode.Create))
{
files[i].CopyTo(stream);
}
if (i == 0)
{
productionUpload.Documents = dbPath;
}
else
{
productionUpload.CoverLetter = dbPath;
}
}
_context.SaveChanges();
}
catch (Exception ex)
{
SendExceptionEmail(ex);
_logger.LogError("{0}\n{1}", ex.Message, ex.StackTrace);
throw;
}
}
'home-component.ts'
ngOnInit() {
this.requestForm = this.formBuilder.group({
Id: ['', ''],
ProducingEntity: [null, Validators.required],
PartyCode: [null,Validators.required],
RepresentedBy: [null],
ContactName: [null, Validators.required],
Email: [null, [Validators.required, Validators.pattern(this.emailPattern)]],
ContactNumber: [null, [Validators.required, Validators.pattern(this.phoneNumberPattern)]],
ReferenceNumber: [null],
NoticeToProduceNumber: [null, [Validators.required, Validators.pattern(this.ntpPattern)]],
TrancheNumber: [null, Validators.pattern(this.tranchePattern)],
ReplacementFiles: [null, Validators.required],
UploadMaterial: [null, Validators.required],
Password: [null],
Description: [null],
Recaptcha: [null, Validators.required]
});
this.requestForm.controls.Id.setValue(0);
}
HandleDocumentInput(files: FileList) {
if (files != null && files.length > 0) {
this.ShowDocumentAlertMessage = false;
if (!this.ValidateFileSize(files.item(0), this.maxDocumentSize)) {
this.documentUploader.queue.pop();
this.DocumentAlertMessageType = 2; // failure
this.DocumentMessage = "File size must be greater than 0 and cannot exceed 4GB.";
this.ShowDocumentAlertMessage = true;
this.documentInput.nativeElement.value = '';
return;
}
if (!this.ValidateFileType(files.item(0), this.allowedDocumentExtensions)) {
this.documentUploader.queue.pop();
this.DocumentAlertMessageType = 2; // failure
this.DocumentMessage = "Files with this extension cannot be uploaded.";
this.ShowDocumentAlertMessage = true;
this.documentInput.nativeElement.value = '';
return;
}
this.DocumentFile = files.item(0);
this.DocumentName = files.item(0).name;
this.IsDocumentUploaded = true;
this.documentInput.nativeElement.value = '';
}
}
'app-service.ts'
Submit(productionUpload: ProductionUpload) {
const apiUrl = window.location.href + 'ProductionUpload/Add';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
responseType: 'text' as 'json'
};
productionUpload.ReplacementFiles = +productionUpload.ReplacementFiles;
productionUpload.IsDeleted = false;
productionUpload.IsProcessed = false;
return this._http.post<string>(apiUrl, productionUpload, httpOptions);
}
UploadFile(recaptcha, fileToUpload: File[]) {
const apiUrl = window.location.href + 'ProductionUpload/Upload';
const formData: FormData = new FormData();
if (fileToUpload && fileToUpload.length)
{
fileToUpload.forEach(file => formData.append('files', file));
}
formData.append('data', recaptcha)
return this._http.post(apiUrl, formData);
}
'Exception getting' The client has disconnected
at Microsoft.AspNetCore.Server.IIS.Core.IO.AsyncIOOperation.GetResult(Int16 token) at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.ReadBody() at System.IO.Pipelines.PipeCompletion.ThrowLatchedException() at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result) at System.IO.Pipelines.Pipe.GetReadAsyncResult() at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.ReadAsync(Memory1 memory, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.IIS.Core.HttpRequestStream.ReadAsyncInternal(Memory1 buffer, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.BufferedReadStream.EnsureBufferedAsync(Int32 minCount, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.DrainAsync(Stream stream, ArrayPool1 bytePool, Nullable1 limit, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Features.FormFeature.ReadForm() at Microsoft.AspNetCore.Http.DefaultHttpRequest.get_Form()