Copied to clipboard

Flag this post as spam?

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


  • Barry Fogarty 493 posts 1129 karma points
    May 07, 2015 @ 13:42
    Barry Fogarty
    0

    Handling static file extensions to find content

    Hi guys,

    I'm working on a package which involves generating XML feeds from Umbraco content.  The feeds integrate with a third party service and they will only accept URLs with .xml file extension.  Within the feed I also need to point to further Umbraco content but with .html and .mainfest extensions.

    So in a nutshell I am looking for a solution so 1) Umbraco can handle requests for static file extensions.  Once I have that, I need to be able to 2) get to the correct Umbraco content (e.g. using a ContentFinder).  I'd like to avoid any solution involving IIS changes as it needs to be be installable as an Umbraco package.

    I've looked into creating a httpmodule or handler but I'd be interested to hear anyone else's approach who has tackled this.  If I go down this route, I'm not sure how I would get the Umbraco context as the requested URL will not automatically map to a node.  

     

  • Ismail Mayat 4511 posts 10092 karma points MVP 2x admin c-trib
    May 07, 2015 @ 15:37
    Ismail Mayat
    0

    Barry,

    Not sure if this helps but there is uStaticPublish package source code here https://github.com/PetrSnobelt/UmbracoStaticPublish although that is for umbraco html pages.

    Regards

    Ismail

  • Peter Gregory 408 posts 1614 karma points MVP 3x admin c-trib
    May 07, 2015 @ 15:38
    Peter Gregory
    0

    Hey Barry

    I have done something similar with a handler that processed .json extensions. You can create an Umbraco Context but as as you say you are not on a particular route so CurrentPage etc wont exist so you will have to create some sort of crafty way of figuring out some sort of URL. In my case I didnt need to know the path so it wasn't a big issue.

    Maybe you could do it by making the URLs actual Umbraco URL's with an appended XML file and then the XML file handler could take over? So something like

    http://www.yoursite.com/some/content-path/data.xml
    

    And then in your handler figure out the Umbraco route using the part of the URI before the data.xml (or whatever you want to call it)

    Sorry there's no code.. But maybe the thought might help you figure out a way. Be interested to see how you tackle it.

    Peter

  • Peter Duncanson 430 posts 1360 karma points c-trib
    May 07, 2015 @ 15:40
    Peter Duncanson
    0

    I wonder if you could use Umbracos built in tools.

    * URL rewriter - could you add a re-write rule to remove the .xml file extension I wonder so that it would point to the file (or at least have a go at trying to find it and fall through to a normal 404 after that). You could deploy this as a package using Package Actions to add in the additions to the config file with ease.

    * Add a url alias to the content - a page can be hit via a number of different urls if you add a url alias, this is usable manually if its only a few pages but more likely you want it automated. You could have a DLL that hooks into the DocumentSaved event to add/update a alias with a .xml extension to all content. Again easily deployable and using "Vanilla Umbraco" tools and standards :)

    Simplest solutions often the best.

    Pete

  • Barry Fogarty 493 posts 1129 karma points
    May 07, 2015 @ 18:05
    Barry Fogarty
    0

    Thanks guys, I have investigated some of the solutions and am making progress - #h5yr

    @ismail - this is an interesting approach but I dont want to have to worry about file permissions as its gonna be a package.

    @pete - I had considered URL rewriting but the problem is I won't know any details of the URL and I want to avoid a global .XML rewrite - again due to this being a package.  I also tried url alias and indeed a URL Provider (similar to a content finder), but unfortunately when you add .xml to the URL, Umbraco will not resolve this as it is deemed a client side request - see Shannon's comment here - http://issues.umbraco.org/issue/U4-5445#comment=67-16816.  Otheriwise than that your suggestion would have been a great simple solution!

    @peter - this was a great suggestion and got me well along the path.  I have a handler intercepting .xml requests and I can determine the node I want to display by chopping the XML part from the URL as you suggested.  Currently I simply redirect to the Umbraco path.  My problem is though - I only want to do this when a node is found - i.e. sitemap.xml should fall back and be processed by the default handler.  I havent figured that part out yet, I'm hoping there's a way.

    I'm also trying to figure out how to inject the umbraco URL's response content to my current respose (so I don't have to issue a redirect).

    Thanks for your help so far any other thoughts greatly appreciated!

  • Barry Fogarty 493 posts 1129 karma points
    May 07, 2015 @ 19:22
    Barry Fogarty
    1

    Further update, here is my handler code:

    public class FeedXmlHandler : IHttpHandler
        {
            public bool IsReusable
            {
                get { return true; }
            }
    
            public void ProcessRequest(HttpContext httpContext)
            {
                // Get the equivalent Umbraco URL from the request
                var originalUrl = httpContext.Request.Url.PathAndQuery;
                var umbracoPath = originalUrl.Replace(".xml", string.Empty);
    
                // We need to ensure we have an Umbraco context so we can search for our node, see
                // http://issues.umbraco.org/issue/U4-5445#comment=67-16816
                var httpContextWrapper = new HttpContextWrapper(httpContext);
                UmbracoContext.EnsureContext(httpContextWrapper,
                                            ApplicationContext.Current,
                                            new WebSecurity(httpContextWrapper, ApplicationContext.Current),
                                            true);   
    
                // Search for a matching node by path (or ID this is passed in the original request)
                var node = UmbracoContext.Current.ContentCache.GetByRoute(umbracoPath);
    
                if (node != null)
                {
                    // Return the content of the Umbraco route
                    httpContext.Server.TransferRequest(umbracoPath);
                }
                else
                {
                    // Serve static content TODO - can I just pass this back to the default Http Handler?:
                    Type type = typeof(HttpApplication).Assembly.GetType("System.Web.StaticFileHandler", true);
                    IHttpHandler handler = (IHttpHandler)Activator.CreateInstance(type, true);
                    handler.ProcessRequest(httpContext);
                }
    
            }

    Now I have the requst transferring to my Umbraco node (if it exists), and if not the request is passed back to the static file handler.  I would like to pass the request back to a more generic handler, so it can be processed correctly even if its not a static file.  Perhaps I am doing this wrong, and I need to look at a httpModule?  Anyway thanks for you help so far, I'm 95% of the way there with this I think. Hope this can be of assistance to others.

     

Please Sign in or register to post replies

Write your reply to:

Draft