I'm trying to get the telerik upload in grid working, and since the upload control is on a tab, I think I need to change the onupload javascript call, but I'm not sure what to change. I can't get the datakey passed in properly....
I'm trying to get this demo to work with a tab:
http://www.telerik.com/community/code-library/aspnet-mvc/upload/upload-in-grid.aspx
6 Answers, 1 is accepted
Hello, I'm always getting null for the datakey on the SaveFile method. Any idea why? I'm using the code example from the library I metioned above.
from attachment.ascx editor template:
function onUpload(e) {
var grid = $(this).closest(".t-grid").data("tGrid");
var tr = $(this).closest("tr");
var dataItem = grid.dataItem(tr);
if (dataItem) {
e.data = { id: dataItem.StudentID };
}
}
controller:
[HttpPost]
public ActionResult SaveFile(string id, HttpPostedFileBase attachment)
{
var attachmentName = Path.GetFileName(attachment.FileName);
var imagesPath = Server.MapPath("~/App_Data/StudentFiles/");
attachment.SaveAs(Path.Combine(imagesPath, attachmentName));
return Json(new { fileName = attachmentName }, "text/plain");
}
grid (this is a tab):
items.Add().Text("Files").Content(
Html.Telerik().Grid<AMClinicals.Models.StudentFile>()
.Name("Files_<#= StudentID #>")
.ToolBar(commands => commands.Insert())
//.DataKeys(keys => keys.Add(f => f.StudentID))
.DataKeys(keys => keys.Add("StudentID"))
.Columns(columns =>
{
columns.Bound(f => f.File).ClientTemplate("<ul class='t-menu'><li><a href='" + Url.Action("DownloadFile", "Student", new { id = "<#=StudentFileID#>" }) + "' class='t-link' ><#=FileType.FileTypeName#></a></li></ul>").Title("Files");
columns.Command(command =>
{
command.Edit().ButtonType(GridButtonType.Image);
command.Delete().ButtonType(GridButtonType.Image);
}).Width(50);
})
//.Editable(editable => editable.Mode(GridEditMode.PopUp))
.ClientEvents(events => events.OnSave("onFileSave"))
.DataBinding(dataBinding => dataBinding.Ajax()
.Update("UpdateStudentFile", "Student")
.Insert("InsertStudentFile", "Student")
.Delete("DeleteStudentFile", "Student", new { id = "<#= StudentID #>" })
.Select("SelectStudentFile", "Student", new { id = "<#= StudentID #>" }))
.ToHtmlString());
I just modified the sample project that I was referrring to with a tab, and still can't get the id (datakey) to show when saving the file. Please help.
Thanks...
See attachment.
Thanks..
Thank you for sending a working project. However I'm unable to replicate the issue that you're having.
Editing a record always sends the id to the Save action. The id is missing only upon inserting a new record which is expected as no such record exists on the server yet.
Can you please explain in more detail the steps I need to take in order to reproduce the issue? Please feel free to directly record a video using Jing (free service).
Tsvetomir Tsonev
the Telerik team
Thanks for responding. In my database I have a one 1 many relationship. Students (1) to Files (many). So, when I insert a new file, I need the studentid to be able to put in the app_data/studentfiles/studentid folder. My main grid has the studentid, and then I wanted to get the studentid on my files tab (located in the detail view) through the datakey or client template? like <# StudentID #>.
I think the first problem is that my datakey id is an int. In the sample project the datakey is a string. If you change it to an int, you'll get a response 500 error.
On the SaveFile, I need that datakey because I need to specify the directory. I have it to string below but it needs be int id.
[HttpPost]
public ActionResult SaveFile(string id, HttpPostedFileBase attachment)
{
var attachmentName = Path.GetFileName(attachment.FileName);
var imagesPath = Server.MapPath("~/App_Data/StudentFiles/" + id + "/");
attachment.SaveAs(Path.Combine(imagesPath, attachmentName));
return Json(new { fileName = attachmentName }, "text/plain");
}
I tried jing, but couldn't get it to work.... but if you need a video I can supply one from somewhere else.
The Upload is configured to operate in async mode and the files are uploaded as soon as they are selected. This basically guarantees you that the student record does not exist at the moment of upload.
The solution is to keep the uploaded files in a temporary location and associate them with the student record when it is available.
You need to check if the id is available in the SaveFile handler:
[HttpPost]public ActionResult SaveFile(int? id, HttpPostedFileBase attachment){ var attachmentName = Path.GetFileName(attachment.FileName); string imagesPath; if (id.HasValue) { // Editing an existing record imagesPath = Server.MapPath("~/App_Data/StudentFiles/" + id + "/"); } else { // Inserting a new record imagesPath = Server.MapPath("~/App_Data/Staging/"); } attachment.SaveAs(Path.Combine(imagesPath, attachmentName)); return Json(new { fileName = attachmentName }, "text/plain");}Note that we're using a nullable int - otherwise you'll get the server error you mention.
[HttpPost][GridAction]public ActionResult Insert(){ var employee = new Employee(); if (TryUpdateModel(employee)) { employee.ID = Guid.NewGuid().ToString(); Model.Add(employee); } // Move the file specified in employee.fileName // from ~/App_Data/Staging/ to ~/App_Data/StudentFiles/id // ... return View(new GridModel(Model));}I hope this helps.
Tsvetomir Tsonev
the Telerik team