public ActionResult TicketFiles(int ticketId) { var attachments = TicketDeskFileStore.ListAttachmentInfo(ticketId.ToString(CultureInfo.InvariantCulture), false); ViewBag.TicketId = ticketId; return(PartialView("_TicketFiles", attachments)); }
public ActionResult GetAttachmentsInfo(int?id, Guid?tempId) { var pending = tempId.HasValue ? TicketDeskFileStore.ListAttachmentInfo(tempId.Value.ToString(), true) : new TicketDeskFileInfo[0]; var attached = id.HasValue ? TicketDeskFileStore.ListAttachmentInfo(id.Value.ToString(CultureInfo.InvariantCulture), false) : new TicketDeskFileInfo[0]; var files = pending.Select(f => tempId != null ? new { f.Name, f.Size, isAttached = false, Type = MimeTypeMap.GetMimeType(Path.GetExtension(f.Name)), Url = Url.RouteUrl("GetPendingFile", new { Id = tempId.Value, FileName = f.Name, }) } : null) .Union(attached.Select(f => id != null ? new { f.Name, f.Size, isAttached = true, Type = MimeTypeMap.GetMimeType(Path.GetExtension(f.Name)), Url = Url.RouteUrl("GetAttachedFile", new { Id = id.Value, FileName = f.Name }) } : null)); return(new JsonCamelCaseResult { Data = files, JsonRequestBehavior = JsonRequestBehavior.AllowGet }); }
public async Task <ActionResult> TicketDetails(int ticketId) { var ticket = await Context.Tickets.FindAsync(ticketId); ViewBag.Attachments = TicketDeskFileStore.ListAttachmentInfo(ticketId.ToString(CultureInfo.InvariantCulture), false); return(PartialView("_TicketDetails", ticket)); }
public JsonResult Delete(Guid id, string fileName) { //ticketdesk never lets the UI directly delete a file attachment unless it is a pending. TicketDeskFileStore.DeleteAttachment(fileName, id.ToString(), true); return(new JsonCamelCaseResult { Data = new { Message = string.Empty } }); //dropzone expects a message property back }
public ActionResult TicketFiles(int ticketId) { //WARNING! This is also used as a child action and cannot be made async in MVC 5 var attachments = TicketDeskFileStore.ListAttachmentInfo(ticketId.ToString(CultureInfo.InvariantCulture), false); ViewBag.TicketId = ticketId; return(PartialView("_TicketFiles", attachments)); }
public async Task <ActionResult> Upload(Guid tempId) { //TODO: doesn't necessarily play well with large files, cap file upload size to something reasonable (define in settings) or use upload chunking foreach (string fileName in Request.Files) { var file = Request.Files[fileName]; Debug.Assert(file != null, "file != null"); await TicketDeskFileStore.SaveAttachmentAsync(file.InputStream, file.FileName, tempId.ToString(), true); } return(Json(new { Message = string.Empty }));//dropzone expects a message property back }
public async Task <ActionResult> ModifyAttachments(int ticketId, [ModelBinder(typeof(SummernoteModelBinder))] string comment, Guid tempId, string deleteFiles) { var demoMode = (ConfigurationManager.AppSettings["ticketdesk:DemoModeEnabled"] ?? "false").Equals("true", StringComparison.InvariantCultureIgnoreCase); if (demoMode) { return(new EmptyResult()); } //most of this action is performed directly against the storage provider, outside the business domain's control. // All the business domain has to do is record the activity log and comments Action <Ticket> activityFn = ticket => { //TODO: it might make sense to move the string building part of this over to the TicketDeskFileStore too? var sb = new StringBuilder(comment); if (!string.IsNullOrEmpty(deleteFiles)) { sb.AppendLine(); sb.AppendLine("<dl><dt>"); sb.AppendLine(Strings.RemovedFiles); sb.AppendLine("</dt>"); var files = deleteFiles.Split(','); foreach (var file in files) { TicketDeskFileStore.DeleteAttachment(file, ticketId.ToString(CultureInfo.InvariantCulture), false); sb.AppendLine(string.Format("<dd> {0}</dd>", file)); } sb.AppendLine("</dl>"); } var filesAdded = ticket.CommitPendingAttachments(tempId).ToArray(); if (filesAdded.Any()) { sb.AppendLine(); sb.AppendLine("<dl><dt>"); sb.AppendLine(Strings.NewFiles); sb.AppendLine("</dt>"); foreach (var file in filesAdded) { sb.AppendLine(string.Format("<dd> {0}</dd>", file)); } sb.AppendLine("</dl>"); } comment = sb.ToString(); //perform the simple business domain functions var domainActivityFn = Context.TicketActions.ModifyAttachments(comment); domainActivityFn(ticket); }; return(await PerformTicketAction(ticketId, activityFn, TicketActivity.ModifyAttachments)); }
/// <summary> /// Commits any pending attachments for the ticket in the file store. /// </summary> /// <param name="ticket">The ticket.</param> /// <param name="tempId">The temporary identifier for pending attachments.</param> /// <returns>IEnumerable<System.String>. The list of filenames for all attachments saved</returns> public static IEnumerable <string> CommitPendingAttachments(this Ticket ticket, Guid tempId) { var attachments = TicketDeskFileStore.ListAttachmentInfo(tempId.ToString(), true).ToArray(); foreach (var attachment in attachments) { TicketDeskFileStore.MoveFile( attachment.Name, tempId.ToString(), ticket.TicketId.ToString(CultureInfo.InvariantCulture), true, false); } return(attachments.Select(a => a.Name)); }
private void MigrateImages() { const string contentQueryText = "SELECT FileContents FROM dbo.TicketAttachments WHERE FileId = @p0"; const string modelQuery = "SELECT TicketId, FileId, FileName, FileSize, IsPending FROM dbo.TicketAttachments"; const int pgSize = 20; using (var ctx = new TdDomainContext(null)) { var q = ctx.Database.SqlQuery <TicketAttachment>(modelQuery); var numRec = q.Count(); RaiseStatusChangedOnMainThread(new[] { string.Format("Importing {0} Images from legacy database.", numRec) }); var i = 0; while (i < numRec) { var res = q.Skip(i).Take(pgSize).ToArray(); i += pgSize; foreach (var file in res) { if (file.TicketId.HasValue) { var container = file.TicketId.Value.ToString(CultureInfo.InvariantCulture); if (!TicketDeskFileStore.FileExists(file.FileName, container, false)) { var contentQuery = ctx.Database.SqlQuery <byte[]>(contentQueryText, file.FileId); var stream = new MemoryStream(contentQuery.First()); TicketDeskFileStore .SaveAttachmentAsync(stream, file.FileName, container, false) .Wait(); RaiseStatusChangedOnMainThread(new[] { string.Format(" Image {0} for ticket #{1} imported.", file.FileName, file.TicketId) }); } else { RaiseStatusChangedOnMainThread(new[] { string.Format(" Image {0} for ticket #{1} already exists, skipping.", file.FileName, file.TicketId) }); } } } } RaiseStatusChangedOnMainThread(new[] { "Image import complete." }); } }
public async Task <ActionResult> ModifyAttachments(int ticketId, string comment, Guid tempId, string deleteFiles) { //most of this action is performed directly against the storage provider, outside the business domain's control. // All the business domain has to do is record the activity log and comments Action <Ticket> activityFn = ticket => { //TODO: it might make sense to move the string building part of this over to the TicketDeskFileStore too? var sb = new StringBuilder(comment); if (!string.IsNullOrEmpty(deleteFiles)) { sb.AppendLine(); sb.AppendLine("<pre>"); sb.AppendLine("Removed Files:"); var files = deleteFiles.Split(','); foreach (var file in files) { TicketDeskFileStore.DeleteAttachment(file, ticketId.ToString(CultureInfo.InvariantCulture), false); sb.AppendLine(string.Format(" {0}", file)); } sb.AppendLine("</pre>"); } var filesAdded = ticket.CommitPendingAttachments(tempId).ToArray(); if (filesAdded.Any()) { sb.AppendLine(); sb.AppendLine("<pre>"); sb.AppendLine("New files:"); foreach (var file in filesAdded) { sb.AppendLine(string.Format(" {0}", file)); } sb.AppendLine("</pre>"); } comment = sb.ToString(); //perform the simple business domain functions var domainActivityFn = Context.TicketActions.ModifyAttachments(comment); domainActivityFn(ticket); }; return(await PerformTicketAction(ticketId, activityFn, TicketActivity.ModifyAttachments)); }
public async Task <ActionResult> Upload(Guid tempId) { var demoMode = (ConfigurationManager.AppSettings["ticketdesk:DemoModeEnabled"] ?? "false").Equals("true", StringComparison.InvariantCultureIgnoreCase); if (demoMode) { return(new EmptyResult()); } //TODO: doesn't necessarily play well with large files, cap file upload size to something reasonable (define in settings) or use upload chunking foreach (string fileName in Request.Files) { var file = Request.Files[fileName]; Debug.Assert(file != null, "file != null"); await TicketDeskFileStore.SaveAttachmentAsync(file.InputStream, file.FileName, tempId.ToString(), true); } return(new JsonCamelCaseResult { Data = new { Message = string.Empty } }); //dropzone expects a message property back }
private ActionResult FetchFile(string fileName, string container, bool isPending) { var fstream = TicketDeskFileStore.GetFile(fileName, container, isPending); return(new FileStreamResult(fstream, "application/octet-stream"));//always send it back as octet-stream so client browser actually downloads it, instead of displaying it on-screen }