Kendo UI Core - Download - How to invoke an MVC controller
I am using Kendo UI Core (free version) and want to upload files to a web server (via MVC controller). I know a way with the paid version of Kendo UI, but I want to do it with the free version of that.
See below
HTML to load Kendo UI
<div class="demo-section k-header">
<input name="files" id="files" type="file" />
</div>
Java Script
$("#files").kendoUpload({
async: {
saveUrl: "save",
removeUrl: "remove",
autoUpload: true
}
});
It adds a button as shown below:
Now when I select the files, I want to upload them to the server via an MVC controller.
How do I make a call to the MVC controller here?
Greetings
source to share
For Kendo UI core (as per your question calling controller action to download files): -
$("#files").kendoUpload({
async: {
saveUrl: "controllername/actionname", //OR// '@Url.Action("actionname", "controllername")'
removeUrl: "controllername/actionname", //OR// '@Url.Action("actionname", "controllername")'
autoUpload: true
}
});
For example, if the name of the controller and action Upload
and Save
to save and delete the loaded files, the name of the controller and action Upload
and Remove
, then:
$("#files").kendoUpload({
async: {
saveUrl: "Upload/Save", //OR// '@Url.Action("Save", "Upload")'
removeUrl: "Upload/Remove", //OR// '@Url.Action("Remove", "Upload")'
autoUpload: true
}
});
Small demo of Kendo file upload (for kendo ui web): -
View: -
<form method="post" action='@Url.Action("Submit")' style="width:45%">
<div class="demo-section">
@(Html.Kendo().Upload()
.Name("files")
)
<p>
<input type="submit" value="Submit" class="k-button" />
</p>
</div>
</form>
Controller: -
public ActionResult Submit(IEnumerable<HttpPostedFileBase> files)
{
if (files != null)
{
TempData["UploadedFiles"] = GetFileInfo(files);
}
return RedirectToAction("Index");
}
private IEnumerable<string> GetFileInfo(IEnumerable<HttpPostedFileBase> files)
{
return
from a in files
where a != null
select string.Format("{0} ({1} bytes)", Path.GetFileName(a.FileName), a.ContentLength);
}
Full documentation is here: - http://demos.telerik.com/aspnet-mvc/upload/index
To download the Async file: -
View: -
<div style="width:45%">
<div class="demo-section">
@(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("Save", "Upload")
.Remove("Remove", "Upload")
.AutoUpload(true)
)
)
</div>
</div>
Controller: -
public ActionResult Save(IEnumerable<HttpPostedFileBase> files)
{
// The Name of the Upload component is "files"
if (files != null)
{
foreach (var file in files)
{
// Some browsers send file names with full path.
// We are only interested in the file name.
var fileName = Path.GetFileName(file.FileName);
var physicalPath = Path.Combine(Server.MapPath("~/App_Data"), fileName);
// The files are not actually saved in this demo
// file.SaveAs(physicalPath);
}
}
// Return an empty string to signify success
return Content("");
}
public ActionResult Remove(string[] fileNames)
{
// The parameter of the Remove action must be called "fileNames"
if (fileNames != null)
{
foreach (var fullName in fileNames)
{
var fileName = Path.GetFileName(fullName);
var physicalPath = Path.Combine(Server.MapPath("~/App_Data"), fileName);
// TODO: Verify user permissions
if (System.IO.File.Exists(physicalPath))
{
// The files are not actually removed in this demo
// System.IO.File.Delete(physicalPath);
}
}
}
// Return an empty string to signify success
return Content("");
}
source to share
I had a bit of a "Duh" moment with this and realized that if you don't set the .SaveField property then the name of the control should be the same as the parameter on the controller.
Code on a .cshtml page using SaveField:
Html.Kendo().Upload()
.Multiple(false)
.Name("controlName")
.Async(a => a
.Save("SavePhoto", "Upload")
.AutoUpload(true)
.SaveField("fileParameter")
);
Sample controller:
public ActionResult SavePhoto(IFormFile fileParameter)
If you don't specify SaveLoad:
Html.Kendo().Upload()
.Multiple(false)
.Name("uploadFiles")
.Async(a => a
.Save("SavePhoto", "Upload")
.AutoUpload(true)
);
It won't work. In this case, the name of the control must match the parameter in the controller:
public ActionResult SavePhoto(IFormFile uploadFiles)
source to share
Customize your wrappers to save time
@(Html.Kendo().Upload().HtmlAttributes(new { Style = "width:300px;" })
.Name("upImport")
.Messages(e => e.DropFilesHere("Drop files here").Select("Select file"))
.Multiple(false)
.Async(a => a
.Save("UploadFile", "File")
.Remove("RemoveFile", "File")
.AutoUpload(true)
.SaveField("files")
)
.Events(events => events
.Error("onError")
.Success("onSuccess")
)
)
On your server mvc app, maybe you have FileService.UploadFile () or something similar.
public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> files)
{
ServerFileModel model = new ServerFileModel();
try
{
// The Name of the Upload component is "files"
if (files == null || files.Count() == 0)
throw new ArgumentException("No files defined");
HttpPostedFileBase file = files.ToArray()[0];
if (file.ContentLength > 10485760)
throw new ArgumentException("File cannot exceed 10MB");
file.InputStream.Position = 0;
Byte[] destination = new Byte[file.ContentLength];
file.InputStream.Read(destination, 0, file.ContentLength);
//IGNORE THIS
ServerFileFormatEnum type = TempFileStorageController.GetFileFormatForExtension(Path.GetExtension(file.FileName));
ServerFileDescriptor serverFile = TempFileStorageController.AddFile(destination, type);
//IGNORE ABOVE
model.FileIdentifier = serverFile.FileIdentifier;
model.FileName = file.FileName;
model.FileSize = file.ContentLength;
}
catch (Exception e)
{
model.UploadError = e.Message;
}
return Json(model, JsonRequestBehavior.AllowGet);
}
source to share
Finally it worked:
It worked as follows.
$("#files").kendoUpload({
async: {
saveUrl: '@Url.Action("Save", "Home")',
removeUrl: '@Url.Action("Remove", "Home")',
autoUpload: false
}
});
This is how I made a call to the Kendo UI window management window and it worked the same as Upload
Save action (function) and Home is the name of the controller class
source to share