Adding files to an Angular ViewModel using DropzoneJS

I am facing a challenge in extracting file content and inserting it into a specific FileViewModel. This is necessary because I need to bundle all files with MainViewModel which contains a list of FileViewModel before sending it from the client (angular) to the server (.Net WebApi).

Does anyone have suggestions on how to approach this implementation?

Client ViewModels:

exprot class MainRequestViewModel{
  public FirstName: string;
  public LastName: string;
  public Comments: string;
  public FilesToUpload: Array<FileItemRequestViewModel>;
}

export class FileItemRequestViewModel{
  public FileContent: ArrayBuffer = null;
  public FileMimeType: string;
  public FileName: string;
  public NumberOfPagesInFile: number;
  public ItemPriority: number;
}

Answer №1

Here are a couple of recommendations:

1) For smaller files, such as images and attachments, consider sending them base64encoded over the wire while being mindful of payload limits defined in your webapi's web.config file.

In your entity model, include a property:

fileAsBase64: string

This allows you to convert a file from the dropzone component into a base64 string using the following method:

getBase64(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result);
      reader.onerror = (error) => reject(error);
});

On the C# side, define the file as a string and use it to convert the string back to a byte array:

 public class UploadedFileDto
    {
        public string Name { get; set; }
        public string FileAsBase64 { get; set; }

        [JsonIgnore]
        public string MimeType => Regex.Match(FileAsBase64, @"data:(?<type>.+?);base64,(?<data>.+)").Groups["type"].Value;

        [JsonIgnore]
        public byte[] Bytes =>
            Convert.FromBase64String(Regex.Match(FileAsBase64, @"data:(?<type>.+?);base64,(?<data>.+)").Groups["data"].Value);

    }

2) When dealing with larger files, consider sending the files in a separate call to the server and saving them temporarily. You will also need a function to clean these temporary files. Here is a controller snippet that includes size checks and only allows PDF files:

public async Task<HttpResponseMessage> Upload()
    {


        Dictionary<string, object> dict = new Dictionary<string, object>();
        try
        {

            var httpRequest = HttpContext.Current.Request;

            foreach (string file in httpRequest.Files)
            {

                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);

                var postedFile = httpRequest.Files[file];


                if (postedFile != null && postedFile.ContentLength > 0)
                {
                    int MaxContentLength = 1024 * 1024 * 50; //Size = 50 MB  

                    IList<string> AllowedFileExtensions = new List<string> { ".pdf" };
                    var ext = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf('.'));
                    var extension = ext.ToLower();
                    if (!AllowedFileExtensions.Contains(extension))
                    {

                        var message = string.Format("Please upload file of type .pdf");

                        dict.Add("error", message);
                        return await Task.FromResult(Request.CreateResponse(HttpStatusCode.BadRequest, dict));
                    }
                    else if (postedFile.ContentLength > MaxContentLength)
                    {

                        var message = string.Format("Please upload a file upto 50 mb.");

                        dict.Add("error", message);
                        return await Task.FromResult(Request.CreateResponse(HttpStatusCode.BadRequest, dict));
                    }
                    else
                    {
                        _fileService.SaveUploadedFile(postedFile);

                    }
                }

                var message1 = string.Format("File uploaded Successfully.");
                return await Task.FromResult(Request.CreateResponse(HttpStatusCode.OK, message1)); ;
            }
            var res = string.Format("Please upload a pdf.");
            dict.Add("error", res);
            return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
        }
        catch (Exception ex)
        {
            Log.Error(ex);
            var res = string.Format("Errors occured");
            dict.Add("error", res);
            return await Task.FromResult(Request.CreateResponse(HttpStatusCode.InternalServerError, dict));
        }
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for removing the Angular IDE plugin from Eclipse Oxygen?

After using the free license for 8 days, I found myself needing to continue working. My first attempt at uninstalling Angular-IDE through Eclipse Marketplace Installed screen was unsuccessful. Next, I tried removing Webclipse, but this also did not ...

What is the best way to showcase a file edited in Emacs within Atom?

The coding project I'm working on is built with Typescript, but I don't believe that's relevant. I've noticed that Emacs has a unique approach to indentation. According to the documentation, in Text mode and similar major modes, the TAB ...

Angular - Acquire reference to the <audio> element

Is there a way to access the methods of an audio tag within my component in order to implement play and pause functions based on click events? The current method I tried does not allow me to access the play() function. How can I correctly approach this? ...

What is the best way to duplicate a Typescript class object while making changes to specific properties?

I have a Typescript cat class: class Kitty { constructor( public name: string, public age: number, public color: string ) {} } const mittens = new Kitty('Mittens', 5, 'gray') Now I want to create a clone of the inst ...

a guide on accessing key value elements within an array using Ionic 3

Just diving into the world of Ionic, I am currently working on a task to showcase products on the cart page that have been added to the cart. Upon fetching data from a REST API, I can see the response below in the console. "items": { "29.2.2.0.YTowOnt ...

Nest.js: initializing properties from a superclass in a controller

I have a question about unit testing controllers in the Nest.js framework. My issue is that the property from a superclass is not initialized in the controller class when creating a test module. Here is an example of the code I am referring to: export cl ...

What is the method for placing a title in the initial column with the help of v-simple-table from Vuetify.js?

I am interested in using the v-simple-table UI component from Vuetify.js to create a table similar to the one shown below. After creating the code in codesandbox and previewing the output, I noticed that the title is not aligned properly. HTML↓ < ...

A data type representing a specific category rather than a specific object

My job involves working with Sequalize models, which are essentially classes. Upon registration, these models are populated with some data that needs to be stored. To accomplish this, I store them in a list. However, when retrieving a model into a variab ...

The attribute 'pixiOverlay' is not found in the property

Working on my Angular 8 project, I needed to display several markers on a map, so I chose to utilize Leaflet. Since there were potentially thousands of markers involved, I opted for Leaflet.PixiOverlay to ensure smooth performance. After installing and imp ...

The extended class possesses a distinct type from the base class, which is reinforced by an interface

Is it possible to write a method that is an extension of a base class, but with a different return type, if supported by the shared interface, without adding a type declaration in class 'a'? In practical terms, classes a & b exist in JavaScript ...

What could be causing Typescript Compile Errors to occur during runtime?

In the Visual Studio React + Redux template project, I have created a react component with the following "render()" method: public render() { return ( <React.Fragment> <h1>Welcome to the Adventure Company {th ...

leveraging parcel for importing typescript dependencies

I am currently using parcel to process typescript for a web extension. I have installed JQuery and its type definitions via npm. In my typescript file, I have the following at the top: import $ from "jquery"; import "bootstrap"; However, when running run ...

Utilize an array as the response model in Amazon API Gateway using the AWS CDK

I am currently in the process of developing a TypeScript AWS CDK to set up an API Gateway along with its own Swagger documentation. One of the requirements is to create a simple endpoint that returns a list of "Supplier", but I am facing challenges in spec ...

Organizing Ionic Cards in Alphabetical Order

I'm working on a personal project where I want to implement an alphabetical filter. Each time I create an Ionic card, I intend for it to be filtered by the first name, such as Andre, Amber, Beckc, etc... Here's what I have so far: https://gyazo.c ...

Unlocking $refs with the Composition API in Vue3 - A step-by-step guide

I am currently exploring how to access $refs in Vue 3 using the Composition API. In my template, I have two child components and I specifically need to obtain a reference to one of them: <template> <comp-foo /> <comp-bar ref="ta ...

An object may be null when its type is A or undefined, but we are certain it is not undefined

Since the release of version 4.8.4, the TypeScript compiler has been flagging an issue with the following code: type A = {v: number} function get_the_first<T>(xs: T[]): T | undefined { if (xs.length > 1) return xs[0]; else ...

Sharing functions between Angular components

Check out my problem statement: https://stackblitz.com/edit/angular-jk8dsj I'm facing two challenges with this assignment: I need to dynamically add elements in the app.component when clicking a button in the key-value.component. I've tried ...

ngx-timeago encounters errors during deployment of Angular application

When I build my project locally, everything goes smoothly... However, when using aws code build with a docker image and running npx ng build, the following error occurs: #25 41.40 ./node_modules/ngx-timeago/__ivy_ngcc__/fesm2015/ngx-timeago.js:439:76-112 ...

Issue with angular2-powerbi Configuration: Please ensure you specify a type in the configuration, either as an attribute like 'powerbi-type="report"' or within the configuration settings

While attempting to utilize the PowerBI-Angular2 to showcase the embedded Power BI, I encountered the following error: errors.ts:42 ERROR Error: Attempted to embed using configuration {"accessToken":"xxxxx","tokenType":0,"embedUrl":"https://embedded.power ...

Struggling to figure out webhooks with Stripe

I have encountered a strange issue while using Stripe webhooks to process payments on my website. When I set the currency to USD, it prompts me to provide an address outside of India, which is expected. However, when I change the currency to INR, the addre ...