This is a migrated thread and some comments may be shown as answers.

Error: Cannot read property chunkIndex of undefined

2 Answers 1148 Views
Upload
This is a migrated thread and some comments may be shown as answers.
Alexander
Top achievements
Rank 2
Alexander asked on 26 Dec 2020, 03:17 PM

I am trying to use async chunk upload with Web API 2.
But always after first chunk I am receiving message “Cannot read property 'chunkIndex' of undefined”.
What did I do wrong?

 

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web;
using System.Web.Hosting;
using System.Web.Http;
 
namespace UploadWebApi.Controllers
{
    public class UploadController : ApiController
    {
        [DataContract]
        public class ChunkMetaData
        {
            [DataMember(Name = "uploadUid")]
            public string UploadUid { get; set; }
            [DataMember(Name = "fileName")]
            public string FileName { get; set; }
            [DataMember(Name = "contentType")]
            public string ContentType { get; set; }
            [DataMember(Name = "chunkIndex")]
            public long ChunkIndex { get; set; }
            [DataMember(Name = "totalChunks")]
            public long TotalChunks { get; set; }
            [DataMember(Name = "totalFileSize")]
            public long TotalFileSize { get; set; }
        }
 
        public class FileResult
        {
            public bool Uploaded { get; set; }
            public string FileUid { get; set; }
        }
 
        public class Files
        {
            public string Extension { get; set; }
            public string Name { get; set; }
            public int Size { get; set; }
            public string Uid { get; set; }
        }
 
        public IHttpActionResult Save(HttpFileCollection files)
        {
            string path = String.Empty;
            if (files != null)
            {
                for (var i = 0; i < files.Count; i++)
                {
                    path = Path.Combine(HostingEnvironment.MapPath("~/App_Data"), files[i].FileName);
                    files[i].SaveAs(path);
                }
            }
            return Ok("");
        }
 
        public IHttpActionResult Remove(string[] fileNames)
        {
            if (fileNames != null)
            {
                foreach (var fullName in fileNames)
                {
                    var fileName = Path.GetFileName(fullName);
                    var physicalPath = Path.Combine(HostingEnvironment.MapPath("~/App_Data"), fileName);
                    if (File.Exists(physicalPath))
                    {
                        File.Delete(physicalPath);
                    }
                }
            }
            return Ok("");
        }
 
        public void AppendToFile(string fullPath, Stream content)
        {
            try
            {
                using (FileStream stream = new FileStream(fullPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
                {
                    using (content)
                    {
                        content.CopyTo(stream);
                    }
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }
 
        public IHttpActionResult ChunkSave()
        {
            var files = HttpContext.Current.Request.Files;
            var metaData = HttpContext.Current.Request.Form["metadata"];
            if (metaData == null)
            {
                return Save(files);
            }
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(metaData));
            var serializer = new DataContractJsonSerializer(typeof(ChunkMetaData));
            ChunkMetaData somemetaData = serializer.ReadObject(ms) as ChunkMetaData;
            string path = String.Empty;
            if (files != null)
            {
                for (var i = 0; i < files.Count; i++)
                {
                    path = Path.Combine(HostingEnvironment.MapPath("~/App_Data"), somemetaData.FileName);
                    AppendToFile(path, files[i].InputStream);
                }
            }
            FileResult fileBlob = new FileResult();
            fileBlob.Uploaded = somemetaData.TotalChunks - 1 <= somemetaData.ChunkIndex;
            fileBlob.FileUid = somemetaData.UploadUid;
            return Json(fileBlob);
        }
    }
}

2 Answers, 1 is accepted

Sort by
0
Accepted
Aleksandar
Telerik team
answered on 29 Dec 2020, 03:28 PM

Hi Alexander,

A possible reason for the issue observed could be an issue with serialization. What you can try is specifying the serialization settings for the returned FileResult:

public IHttpActionResult ChunkSave()
{
//...
    var settings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
    settings.ContractResolver = new CamelCasePropertyNamesContractResolver();

    return Json(fileBlob,settings);
}

Give this suggestion a try and let me know if it helps resolve the issue.

Regards,
Aleksandar
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Alexander
Top achievements
Rank 2
answered on 30 Dec 2020, 11:57 AM

Yes!

It helped me!

Thank you and Happy New Year :)

Jonas
Top achievements
Rank 1
commented on 10 Jan 2024, 01:15 PM

I am having the exact same issue, but I don't seem to be able to resolve references on the suggested snippet of code, so I'm completely stuck.  Any other suggestions on how to resolve this?
Neli
Telerik team
commented on 12 Jan 2024, 09:13 AM

Hi Jonas, 

As Alexander mentioned previously the described issue is usually due to serizalization which is not something that the Upload as a UI component has control over. However, you can also try the approach demonstrated below for setting the serialization:

public ActionResult Directory_Upload_Chunk_Save(IEnumerable<HttpPostedFileBase> files, string metaData)
{
    .....
    FileResult fileBlob = new FileResult();
    fileBlob.Uploaded = chunkData.TotalChunks - 1 <= chunkData.ChunkIndex;
    fileBlob.FileUid = chunkData.UploadUid;

    var camelCaseFormatter = new JsonSerializerSettings();
    camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver();
    var json = JsonConvert.SerializeObject(fileBlob, camelCaseFormatter);

    return Content(json, "application/json");
}

Regards,

Neli

Tags
Upload
Asked by
Alexander
Top achievements
Rank 2
Answers by
Aleksandar
Telerik team
Alexander
Top achievements
Rank 2
Share this question
or