Copied to clipboard

Flag this post as spam?

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


  • Jon Ratcliffe 20 posts 47 karma points
    Dec 30, 2011 @ 12:20
    Jon Ratcliffe
    1

    Programatically set the value of a property on a document when saved

    Can anyone help with this problem...

    I have a document type with 2 properties called upload and preview (both custom data types). The upload property is a media upload and when the document is saved or published this property gets set to the correct Id for the new media item as expected - all works fine.

    The preview property is designed to show a preview of the uploaded media file on a separate tab in the UI. To build a preview, this property needs the media Id which is stored in the upload property. How do I programatically set the value of the preview property to be identical to the upload property each time the document is saved (or at least each time the upload property value changes)?

    Here is what I have tried

    1) Just after I handle the upload of the media in the first custom data type, I do something like this:

    var doc = new Document(1234);
    doc.getProperty("preview").Value = media.Id.ToString();
    doc.Save();
    umbraco.library.UpdateDocumentCache(1234);

    This works as I can see the changes to the properties being made in the database but they subsequently get wiped out by Umbraco as the document continues to save.

     

    2) Using the BeforeSave event handler in ApplicationBase

    public class DocumentEvents : ApplicationBase
      {
        public DocumentEvents()
        {
          Document.BeforeSave += new Document.SaveEventHandler(Document_BeforeSave);      
        }
        void Document_BeforeSave(Document sender, umbraco.cms.businesslogic.SaveEventArgs e)
        {
          sender.getProperty("preview").Value = sender.getProperty("upload").Value;
          umbraco.library.UpdateDocumentCache(sender.Id);
        }
      }

    This works but requires that the node be reloaded from the content tree before the change is seen by the user (in other words the change is only visible after a page refresh).

    The second attempt is the closest to what I want to achieve but I need the changes to be visible immediately after saving - the extra page refresh is not acceptable.

    I would have thought that programatically setting the values of properties on a document would be a) simple to do and b) a reasonably common thing to want to do but maybe I am wrong?

    Any ideas will be gratefully received!

     

    JonR

     

     

  • Sebastiaan Janssen 5045 posts 15478 karma points MVP admin hq
    Dec 31, 2011 @ 21:20
    Sebastiaan Janssen
    1

    You can get it to refresh after a file has been uploaded with another event handler, this solves most of your problem, but it does redirect you back to the first tab, hope that's not too much of a problem:

    using System;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using umbraco.BusinessLogic;
    using umbraco.cms.businesslogic;
    using umbraco.cms.businesslogic.web;
    
    namespace MyNameSpace.EventHandlers
    {
        public class RefreshOnUpload : ApplicationBase
        {
            public RefreshOnUpload()
            {
                CMSNode.AfterSave += RedirectIfNeeded;
            }
    
            private static void RedirectIfNeeded(object sender, SaveEventArgs e)
            {
                if (sender is Document == false) return;
    
                var doc = sender as Document;
                if (doc == null) return;
    
                if (HttpContext.Current.Request.Files.Count == 0) return;
                if (HttpContext.Current.Request.Files[0] == null) return;
                if (string.IsNullOrEmpty(HttpContext.Current.Request.Files[0].FileName)) return;
    
                //If we have gotten so far, a file is being uploaded, make sure there is a redirect!
                if (((Page)HttpContext.Current.Handler).Items.Contains("RedirectUrl"))
                    ((Page)HttpContext.Current.Handler).Items.Remove("RedirectUrl");
    
                ((Page)HttpContext.Current.Handler).Items.Add("RedirectUrl", HttpContext.Current.Request.Url.ToString());
                ((Page)HttpContext.Current.Handler).PreRender += PreRender;
            }
    
            private static void PreRender(object sender, EventArgs e)
            {
                if (((Page)HttpContext.Current.Handler).Items.Contains("RedirectUrl") && !string.IsNullOrEmpty((string)((Page)HttpContext.Current.Handler).Items["RedirectUrl"]))
                    HttpContext.Current.Response.Redirect((string)((Page)HttpContext.Current.Handler).Items["RedirectUrl"]);
            }
        }
    }
  • Jon Ratcliffe 20 posts 47 karma points
    Jan 03, 2012 @ 16:12
    Jon Ratcliffe
    1

    Hi Sebastiaan,

    Thanks for your detailed example - this is exactly what I was looking for!

    (I would give you karma but still don't have enough myself to be able to award karma points to others :-( )

    With a small amount of refactoring I've now got my code doing exactly what I wanted. I don't mind the first tab being selected after save - in my case this is not an issue.

    Thanks once again.

     

    Jon

     

     

     

  • Sebastiaan Janssen 5045 posts 15478 karma points MVP admin hq
    Jan 03, 2012 @ 17:15
    Sebastiaan Janssen
    0

    There, I added 2 karma for the future. It's okay, I have plenty at the moment, thanks for the thought though! 

    Glad it's working for you!

Please Sign in or register to post replies

Write your reply to:

Draft