Upload files inside a grid does not send files to controller

1 Answer 237 Views
Grid Upload
Divya
Top achievements
Rank 1
Divya asked on 26 Jan 2023, 07:53 AM

Hello,

I am using upload as an editor template inside grid. But the actual file selected is not being passed to the controller. The controller save method always shows 0 files. Am I missing something here?

Please find the code snippets below.

Grid:

@(Html.Kendo().Grid<DocumentViewEditModel>
    ().Name("Documents").Columns(c =>
    {
    c.Command(command => { command.Edit(); command.Destroy(); }).Width(220).Visible(@readOnlyForm);
    c.Bound(d => d.DocumentId).Hidden(true);
    c.Bound(d => d.ProjectId).Hidden(true);
    c.Bound(d => d.ScagdocumentId).Title("SCAG Document").Width(140);
    c.ForeignKey(d => d.DocumentCategoryId, (SelectList)ViewData["DocumentCategoryList"]).Title("Document Status *").Width(150);
    c.ForeignKey(d => d.NoticeTypeId, (SelectList)ViewData["NoticeTypeList"]).Title("Notice Type *").Width(220);
    c.ForeignKey(d => d.EirtypeId, (SelectList)ViewData["DocumentTypeList"]).Title("Document Type *").Width(250);
    c.Bound(d => d.DocumentDescription).Title("Project Description *").Width(350).HtmlAttributes(new { style = "white-space: pre-line;" });
    c.Bound(d => d.LogDate).Title("Date Received *").Format("{0: MM/dd/yyyy}").Width(170);
    c.Bound(d => d.DueDate).Title("Due Date for Comment").Format("{0: MM/dd/yyyy}").Width(180);
    c.Bound(d => d.DateModified).Title("Date Modified").Format("{0: MM/dd/yyyy}").Width(120);
    c.Bound(d => d.ModifiedBy).Title("Modified By").Width(130);
    c.Bound(d => d.DocumentUploadEditor).EditorTemplateName("DocumentUploadEditor").Title("Upload").ClientTemplate("#:Filename#").Width(150);
    c.Command(command => command.Custom("View").Click("navigateToOpen")).Width(190);
    })
    .DataSource(d => d
    .Ajax()
    .Events(events => events.Error("error_handler"))
    .Read(r => r.Action("GetDocuments", "Projects").Data("getAdditionalData"))
    .Update(u => u.Action("UpdateDocuments", "Projects"))
    .Destroy(x => x.Action("DeleteDocuments", "Projects"))
    .Create(c => c.Action("CreateDocuments", "Projects").Data("getAdditionalData"))
    .PageSize(10)
    .Model(m =>
    {
    m.Id(d => d.DocumentId);
    m.Field("DocumentCategoryId", typeof(int));
    m.Field("NoticeTypeId", typeof(int));
    m.Field("EirtypeId", typeof(int));
    m.Field(d => d.DocumentDescription);
    m.Field(d => d.LogDate);
    m.Field(d => d.DueDate);
    m.Field("ScagdocumentId", typeof(string)).Editable(false);
    m.Field(d => d.ModifiedBy).Editable(false);
    m.Field(d => d.DateModified).Editable(false);
    m.Field("ProjectId", typeof(int));
    })
    )
    .Pageable()
    .Sortable()
    .Scrollable(s => s.Virtual(GridVirtualizationMode.Columns).Height("auto"))
    .HtmlAttributes(new { style = "width:1420px" })
    .Editable(e => e.Mode(GridEditMode.InLine))
    .ToolBar(toolbar => { if (@readOnlyForm) { toolbar.Create(); } })
    )

 

Editor Template:

@(Html.Kendo().Upload()
        .Name("DocumentUploadEditor")
        .Async(a => a
            .Save("UploadNoticeObjects", "Projects")
            .AutoUpload(true)
        )

        .Events(e => e.Upload("onNoticeUpload")
                .Success("onSuccess"))

 )

 

Controller:

public async Task<IActionResult> UploadNoticeObjects(IEnumerable<IFormFile> DocumentUploadEditor, string noticeDocID, string projectNum, string projectTitle, string projectType, string documentType, string noticeType)
        {
           
            if (DocumentUploadEditor != null)
            {
                foreach (var file in DocumentUploadEditor)
                {
                    var fileContent = ContentDispositionHeaderValue.Parse(file.ContentDisposition);

                    // Some browsers send file names with full path. Only interested in the file name.
                    var fileName = Path.GetFileName(fileContent.FileName.ToString().Trim('"'));

                    using (var memoryStream = new MemoryStream())
                    {
                        await file.CopyToAsync(memoryStream);
                        await _uploadFilesManager.UploadNoticeToSharePoint(fileName, memoryStream, NoticesMetadata,"", "").ConfigureAwait(false);
                    }
                }
            }

            // Return an ok to signify success.
            return Ok();
        }
Divya
Top achievements
Rank 1
commented on 31 Jan 2023, 11:38 PM

Second Approach worked for me.

Thanks!!

1 Answer, 1 is accepted

Sort by
0
Accepted
Mihaela
Telerik team
answered on 27 Jan 2023, 01:50 PM

Hello Divya,

Since I have reviewed the described scenario and answered you in a support thread, I will post the same here in case someone else has the same question:

I examined the provided code snippets, and noticed that when uploading files for a specified Grid record, they are sent to the server as a complex object:

(the payload of the Upload request)

For this reason, the IEnumerable<IFormFile> DocumentUploadEditor collection is empty.

To access the uploaded files through the nested property, I would suggest any of the following approaches:

  • Use the "Request.Form" to get the Form Data payload:
public async Task<IActionResult> UploadNoticeObjects(string noticeDocID, string projectNum, string projectTitle, string projectType, string documentType, string noticeType)
{
   var getFilesToUplaod = Request.Form;
  ...
}

 

  • Create a property of type "IEnumerable<IFormFile>" and pass it in the Action method as per the example below:
public class GridUploadFiles
{
  public IEnumerable<IFormFile> DocumentUploadEditor { get; set; }
}

public async Task<IActionResult> UploadNoticeObjects(GridUploadFiles DocumentUploadEditor, string noticeDocID, string projectNum, string projectTitle, string projectType, string documentType, string noticeType)
{
  foreach (var file in DocumentUploadEditor.DocumentUploadEditor)
  {
    ...
   }
  ...
}

I hope any of these examples will help you to resolve the issue.

 

Regards, Mihaela Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Mrudula
Top achievements
Rank 1
commented on 08 Aug 2023, 07:32 PM

how to send filename from controller back in .net core. I need to update models filename in onsucess method. Any nonblank return value results in File upload failure.
Mihaela
Telerik team
commented on 10 Aug 2023, 02:39 PM

You could return a Json as per the example below:

public async Task<IActionResult> UploadNoticeObjects(GridUploadFiles DocumentUploadEditor, string noticeDocID, string projectNum, string projectTitle, string projectType, string documentType, string noticeType)
{
  string uploadedFileName = "";
  foreach (var file in DocumentUploadEditor.DocumentUploadEditor)
  {
    var fileContent = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
    var fileName = Path.GetFileName(fileContent.FileName.ToString().Trim('"'));
    uploadedFileName = fileName;
    ...
   }
  return Json(new { status = "OK", FileName = uploadedFileName });
}

//View
<script>
    function onSuccess(e) {
        console.log(e.response.FileName);  // Get the name of the uploaded file.
    }
</script>

Let me know if this suggestions works for you.

Tags
Grid Upload
Asked by
Divya
Top achievements
Rank 1
Answers by
Mihaela
Telerik team
Share this question
or