0

I have a problem with sending an attachment in a JavaScript function to a C# method. When I want to send the information to the method that is supposed to save the information about the attachment, I get a problem with inllegal invocation. below is the code from JavaScript

 <div class="file-input-container">
        <label for="fileInput" class="file-label">Wybierz załącznik</label>
        <br />
        <input type="file" id="fileInput" class="file-input" name="file" />
        
    </div>

    <ul id="attachment-list"></ul>
    <hr />
    <script>
        const fileInput = document.getElementById('fileInput');
        const attachmentList = document.getElementById('attachment-list');
        let selectedAttachments = [];

        fileInput.addEventListener('change', handleFileUpload);

        function handleFileUpload(event) {
            const file = event.target.files[0];
            const fileName = file.name;
            const fileType = file.type;

            const reader = new FileReader();
            reader.onload = (e) => {
                const fileContent = new Uint8Array(e.target.result);
                const attachment = {
                    name: fileName,
                    content: fileContent,
                    type: file.type
                };
                selectedAttachments.push(attachment);
                saveAttachmentsToServer(selectedAttachments);
            };
            reader.readAsArrayBuffer(file);


            const listItem = document.createElement('li');
            listItem.classList.add('attachment-item');

            const attachmentName = document.createElement('span');
            attachmentName.classList.add('attachment-name');
            attachmentName.textContent = fileName;

            const attachmentDelete = document.createElement('span');
            attachmentDelete.classList.add('attachment-delete');
            attachmentDelete.addEventListener('click', () => {
                listItem.remove();
            });

            listItem.setAttribute('data-name', fileName);
            listItem.setAttribute('data-type', file.type);

            listItem.appendChild(attachmentName);
            listItem.appendChild(attachmentDelete);
            attachmentList.appendChild(listItem);
         

            event.target.value = '';
        }
        function saveAttachmentsToServer(attachments) {
            const formData = new FormData();
            formData.append('attachments', JSON.stringify(attachments));

            $.ajax({
                url: "?handler=SaveAttachments=" ,
                data: formData,
                success: function () {
                    console.log('Załączniki zapisane');
                },
                error: function (error) {
                    console.error('Wystąpił błąd podczas zapisu załączników', error);
                }
            });
        }
    </script>

and this is the C# method

   public async Task<IActionResult> OnPostSaveAttachments(List<AttachmentData> attachments)
        {
            try
            {
                foreach (var attachmentData in attachments)
                {
                    var attachmentContent = attachmentData.Content;
                    if (attachmentContent != null && attachmentContent.Length > 0)
                    {
                        string attachmentName = attachmentData.Name;
                        string attachmentType = attachmentData.Type;

                        string blobName = Guid.NewGuid().ToString();

                        BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
                        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
                        BlobClient blobClient = containerClient.GetBlobClient(blobName);

                        await blobClient.UploadAsync(attachmentContent, overwrite: true);

                        // Zapisz informacje o załączniku w bazie danych lub innym miejscu, np. na podstawie identyfikatora

                        Console.WriteLine("Załącznik zapisany: " + attachmentName);
                    }
                    else
                    {
                        Console.WriteLine("Błąd: Brak zawartości załącznika.");
                    }
                }

                return Page();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Błąd: " + ex.Message);
                return BadRequest("Wystąpił błąd podczas zapisywania załączników.");
            }
        }
    }

        public class AttachmentData
    {
        public string Name { get; set; }
        public Stream Content { get; set; }
        public string Type { get; set; }
    }

Even when I improve the code so that it is successfully uploaded it is still a problem that in the attachmetn method is count =0. how can this be fixed? The whole project is created in ASP.Net

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
Maksio
  • 23
  • 6
  • In you `JS`, where are you specifying the `OnPostSaveAttachments` method? How does the JS know which controller method to send the data to? – Rahul Sharma Jul 09 '23 at 10:32
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Jul 09 '23 at 17:09

1 Answers1

0

I think the problem is in this part. Because you are sending string from the JS, but in C# you are expecting a list.

 const formData = new FormData();
            formData.append('attachments', JSON.stringify(attachments));

Try changing it to the below code.

  for (let i = 0; i < attachments.length; i++) {
    const attachment = attachments[i];
    formData.append('attachments[' + i + '].Name', attachment.name);
    formData.append('attachments[' + i + '].Content', attachment.content);
    formData.append('attachments[' + i + '].Type', attachment.type);
  }
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
  • I added this code and unhappily it returned an inllegal invocation error – Maksio Jul 09 '23 at 13:20
  • this post could help you on this https://stackoverflow.com/questions/10324594/jquery-illegal-invocation – Vivek Nuna Jul 09 '23 at 13:40
  • thanks helped connect only I don't know why the problem is when I send data to the method because the attachment returns me count=0 ' const formData = new FormData(); for (const attachment of attachments) { formData.append('attachments', attachment); } $.ajax({ url: "?handler=SaveAttachments", data: formData, cache: false, processData: false,' did I add your petla correctly ? – Maksio Jul 09 '23 at 16:12
  • @Maksio I have modified the answer, check now. you need to pass the correct object – Vivek Nuna Jul 09 '23 at 16:47
  • Unfortunately, even after the changes in the C# method, I don't get information about attachments. I don't know if this is a problem caused by formdata ? even though the data is saved, or if it is due to a bad constitution of the method. – Maksio Jul 09 '23 at 18:07
  • You can see the in browser network tab, what request is being sent to the backend – Vivek Nuna Jul 09 '23 at 18:33
  • Yes, yes, I checked it and formdata contains information about the name type and content of the attachment. I used this function for (var key of formData.entries()) { console.log(key[0] + ', ' + key[1]); } – Maksio Jul 09 '23 at 18:53
  • There is a problem with the connection if I don't have the post method it doesn't send me formData while if I add the post method it throws me a connection error error 400 – Maksio Jul 10 '23 at 08:29
  • @Maksio so it’s bad request. It’s not getting what it’s expecting – Vivek Nuna Jul 10 '23 at 11:23
  • Do you have any idea how to solve this problem ? – Maksio Jul 11 '23 at 06:09
  • @Maksio I told you right, that something is wrong with your request, you need to send the exact data format, or you can try sending JSON string and change your method to except string. You can deserialize the string to object in your C# code then – Vivek Nuna Jul 11 '23 at 14:11
  • even when I modify the code where the json is sent I always get an error 400 at the POST method but when I modify the code to GET it goes through and connects but from what I know when sending data using the GET method it may not work very well because GET has a limited number of characters to send. don't understand this error earlier in functions I used ?handler= and it worked now there is a problem with post – Maksio Jul 13 '23 at 08:59