Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Dan 1288 posts 3921 karma points c-trib
    Dec 02, 2011 @ 18:54
    Dan
    0

    Redirect to HTTP handler to prompt PDF download or save upon form submission

    Hi,

    I have a simple Contour form which includes basic text fields (name, email etc) and a hidden text field for a document (pdf) file path which is grabbed from a querystring.  Currently this is being logged correctly, including the document file path from the hidden form field.

    What I'd like to do though is to redirect upon submission of the form to a HTTP handler page which prompts to download or save the file referenced in the hidden field.

    I know it's possible to pick a node to redirect to upon submission, or to define an XPath expression, but how about redirecting to a node with a dynamic querystring (i.e. the file path)?  This doesn't need to be secure, so a querystring is fine.  I just don't know if there's a way to do it with the standard functionality or whether I need to write a custom workflow.

    Can anyone advise?

    Thanks

  • Dan 1288 posts 3921 karma points c-trib
    Dec 12, 2011 @ 20:21
    Dan
    0

    I'm re-visiting this one.  Does anyone know if there's a way to redirect to a URL containing a querystring which is generated from a hidden form field, upon submission of the form? Or does this call for a custom workflow entry?

  • Comment author was deleted

    Dec 13, 2011 @ 11:42

    Yup custom workflow or using the event model would be the way forward, no default stuff in there that will do this

  • Dan 1288 posts 3921 karma points c-trib
    Dec 13, 2011 @ 12:02
    Dan
    0

    Thanks Tim.  So it's possible to do this with only a custom workflow?  I didn't think the workflows allowed you to 'break out' and do something like a HTTP redirect?  Just trying to figure out where exactly to start looking.

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Dec 13, 2011 @ 14:07
    Tom Fulton
    0

    Hi Dan,

    Just a thought, maybe you could create a page in Umbraco that handles the file downloading via a macro (or redirect from there to the HTTP handler).  Then use Contour to redirect to that Umbraco page (via Choose or Xpath), the recordid should be passed in the querystring so you could use that to grab the hidden document field from the Contour record via the API, and redirect to it. 

    Hope this helps (and makes sense..),
    Tom

  • Dan 1288 posts 3921 karma points c-trib
    Dec 13, 2011 @ 14:19
    Dan
    0

    Thanks Tom - I didn't realise the recordid was passed as a parameter in the querystring of the native Contour redirect, but indeed it is.  I'm part way through my custom workflow right now, but not confident that it's actaully going to work, at which point I'll look into grabbing the file details from the Contour recordid after redirect, which should definitely work.  Thanks for the pointer - I'll mark as answer as/when I've got there!

  • Dan 1288 posts 3921 karma points c-trib
    Dec 13, 2011 @ 14:49
    Dan
    3

    Okay, so the workflow does work.  For reference, I created a new Visual Studio project, added references to 'businesslogic', 'umbraco', 'interfaces', 'umbraco.forms.core' and 'umbraco.forms.ui' and created a new C# class with the the following code:

    using System;
    using System.Web;
    using System.Collections.Generic;
    using System.Linq;
    using Umbraco.Forms.Core;
    using Umbraco.Forms.Core.Enums;
    using Umbraco.Forms.Data.Storage;
    using Umbraco.Forms.Core.Services;
    using System.Xml;
    using System.Xml.XPath;
    using Umbraco.Forms.Core.Attributes;
    using umbraco.BusinessLogic;
    using umbraco.interfaces;

    namespace contourRedirect
    {
        public class FormRecordEventHandler : umbraco.BusinessLogic.ApplicationBase
        {
            public FormRecordEventHandler()
            {
                RecordService.RecordApproved += new System.EventHandler<RecordEventArgs>(RecordService_RecordApproved);
            }

            void RecordService_RecordApproved(object sender, RecordEventArgs e)
            {
                var r = (Record)((RecordService)sender).Record;
                if (e.Form.Name == "Resource download")
                {
                    HttpContext.Current.Response.Redirect(string.Format("{0}?id={1}", umbraco.library.NiceUrl(r.UmbracoPageId), r.Id));
                }
            }
        }
    }

    Compiling this and dropping the dll into the bin folder it does the job.

    I could extend it to look up the media file path or id and pass that as a querystring parameter on the redirect URL (currently it's just passing the record id) but really this is just a different way of achieving the same thing as the native Contour 'recordid' parameter, only with a hard-coded dependency on the form name which isn't ideal.  It just puts the logic in a slightly different place.  So I may as well use the native parameter and build a usercontrol to grab that id and return the file for download, as per Tom's suggestion.

    Thanks guys, should be sorted from here!

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Dec 13, 2011 @ 14:59
    Tom Fulton
    0

    Didn't realize you could redirect from a workflow...good to know!

  • Dan 1288 posts 3921 karma points c-trib
    Dec 13, 2011 @ 16:44
    Dan
    2

    Just to wrap this up...  Here's the code to take a media file path which is saved as a field in Contour (named 'Document path') and prompt to save/open the document on submission of the form.  It's not actually bound to the submit event, as discussed above, but called from the redirect destination page using the native Contour redirect.  It's just the bare bones - no error handling etc - and it does rely on the full media path being present and correct, which may not ordinarily be the best solution (it would be more robust to save the file node id rather than the rendered file path, but in this instance the client needs the full file path in their data export so it makes sense just to save it there).  So if anyone needs this in future, just create a usercontrol, assign it to a macro and embed the macro in the page which Contour redirects to.  The usercontrol is something like this:

        public partial class PDFDownload : System.Web.UI.UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                string formId = Request.QueryString["recordid"].ToString();
                RecordStorage recordstorage = new RecordStorage();
                Umbraco.Forms.Core.Record record = recordstorage.GetRecord(new Guid(formId));
                RecordField documentTitleField = record.GetRecordField("Document path");
                string filePath = documentTitleField.ValuesAsString();
                string fileName = "unique-file-name.pdf";
                Response.ClearHeaders();
                Response.ClearContent();
                Response.ContentType = "application/octet-stream";
                Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
                Response.WriteFile(filePath);
                Response.End();
            }
        }

    Hope it helps someone at some point.

Please Sign in or register to post replies

Write your reply to:

Draft