Copied to clipboard

Flag this post as spam?

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


  • Chad Rosenthal 272 posts 474 karma points
    Dec 21, 2010 @ 00:21
    Chad Rosenthal
    0

    Using /base with session variables

    We are currently adding Flash to a site. There are about 20-30 values that are coming from a combination of Umbraco Nodes + Membership information from a 3rd party. So far the membership information is being stored in an object in Session. The site works perfect when I log in and just use the site regularly.

    My hope was to be able to have Flash call a /base method which would return an XML feed. This also works when I hard code in the Membership object. Now when I try to grab users information session, I keep getting a Null Exception.

    I could have sworn this worked, but I could be wrong. Can you do this? Can you grab a session object from a REST call?

    If not, does anyone have any advice to do this?

    Thanks,

    C

  • Aaron Powell 1708 posts 3046 karma points c-trib
    Dec 21, 2010 @ 04:12
    Aaron Powell
    1

    How are you accessing Session? I've seen some posts on this topic before but I haven't worked with /base so I've never looked into it, here's a few that I found though: http://our.umbraco.org/forum/developers/api-questions/13819-Session-acces-in-base-methods?p=0 http://our.umbraco.org/forum/core/general/5154-HttpContextCurrentSession-when-using-rest-extensions?p=0

    It's possible that you can't access Session because of the way the type is instantiated (it's done with Reflection), although I'd expect that HttpContext.Current.Session should work, as that's just a static property which resides in the request life cycle.

  • Chad Rosenthal 272 posts 474 karma points
    Dec 21, 2010 @ 15:24
    Chad Rosenthal
    0

    Thanks. I checked out the articles and apparently, you can't do this without adding a Handler. Apparently, it will be fixed in 4.6, but that doesn't help me now. I've looked at the code in 4.6, and tried to create a .dll to create a handler similar to what was done in the article above, but that failed.

    namespace BaseExtension
    {
        using System;
        using System.IO;
        using System.Reflection;
        using System.Web;
        using System.Web.SessionState;
        using System.Xml;
        using umbraco.presentation.umbracobase;
    
        public class requestModule : IHttpModule
        {
            private HttpApplication mApp;
    
            #region IHttpModule Members
    
            public void Dispose()
            {
            }
    
            public void Init(HttpApplication httpApp)
            {
                //            httpApp.PostAuthorizeRequest += new EventHandler(httpApp_PreRequestHandlerExecute);
                httpApp.PostAcquireRequestState += new EventHandler(httpApp_PostAcquireRequestState);
                httpApp.PostMapRequestHandler += new EventHandler(httpApp_PostMapRequestHandler);
            }
    
            void httpApp_PostMapRequestHandler(object sender, EventArgs e)
            {
                //remove extension and split the url
                HttpApplication httpApp = (HttpApplication)sender;
                string url = httpApp.Context.Request.RawUrl;
    
    
                if (url.ToLower().StartsWith("/base/"))
                {
    
                    if (httpApp.Context.Handler is IReadOnlySessionState || httpApp.Context.Handler is IRequiresSessionState)
                    {
                        // no need to replace the current handler
                        return;
                    }
    
                    // swap the current handler
                    httpApp.Context.Handler = new MyHttpHandler(httpApp.Context.Handler);
    
                }
            }
    
            void httpApp_PostAcquireRequestState(object sender, EventArgs e)
            {
                HttpApplication httpApp = (HttpApplication)sender;
    
                //remove extension and split the url
                string url = httpApp.Context.Request.RawUrl;
    
    
                if (url.ToLower().StartsWith("/base/"))
                {
                    MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;
    
                    if (resourceHttpHandler != null)
                    {
                        // set the original handler back
                        HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
                    }
    
                    if (url.ToLower().Contains(".aspx"))
                        url = url.Substring(0, url.IndexOf(".aspx"));
    
                    object[] urlArray = url.Split('/');
    
                    //There has to be minimum 4 parts in the url for this to work... /base/library/method/[parameter].aspx
                    if (urlArray.Length >= 4)
                    {
                        string extensionAlias = urlArray[2].ToString();
                        string methodName = urlArray[3].ToString();
    
                        httpApp.Response.ContentType = "text/xml";
                        restExtension myExtension = new restExtension(extensionAlias, methodName);
    
                        if (myExtension.isAllowed)
                        {
                            string respone = invokeMethod(myExtension, urlArray);
                            if (respone.Substring(0, 7) == "<error>")
                            {
                                httpApp.Response.StatusCode = 500;
                                httpApp.Response.StatusDescription = "Internal Server Error";
                            }
                            httpApp.Response.Output.Write(respone);
                        }
                        else
                        {
                            httpApp.Response.StatusCode = 500;
                            httpApp.Response.StatusDescription = "Internal Server Error";
                            //Very static error msg...
                            httpApp.Response.Output.Write("<error>Extension not found or permission denied</error>");
                        }
                        //end the resposne
                        httpApp.Response.End();
                    }
                }
            }
    
    
    
    
            private string invokeMethod(restExtension myExtension, object[] paras)
            {
                try
                {
                    //So method is either not found or not valid... this should probably be moved... 
                    if (!myExtension.method.IsPublic || !myExtension.method.IsStatic)
                        return "<error>Method has to be public and static</error>";
                    else //And if it is lets continue trying to invoke it... 
                    {
                        //lets check if we have parameters enough in the url..
                        if (myExtension.method.GetParameters().Length > (paras.Length - 4)) //Too few
                            return "<error>Not Enough parameters in url</error>";
                        else
                        {
    
                            //We have enough parameters... lets invoke..
                            //Create an instance of the type we need to invoke the method from.
                            Object obj = Activator.CreateInstance(myExtension.type);
                            Object response;
    
                            //umbracoBase.baseBinder bBinder = new baseBinder();
    
                            if (myExtension.method.GetParameters().Length == 0)
                            {
                                //response = myMethod.method.Invoke(obj, BindingFlags.Public | BindingFlags.Instance, bBinder, null, System.Globalization.CultureInfo.CurrentCulture);
                                response = myExtension.method.Invoke(obj, null); //Invoke with null as parameters as there are none
                            }
    
                            else
                            {
                                //We only need the parts of the url above the number 4 so we'll 
                                //recast those to objects and add them to the object[]
    
                                //Getting the right lenght.. 4 is the magic number dum di dum.. 
                                object[] methodParams = new object[(paras.Length - 4)];
    
                                int i = 0;
    
                                foreach (ParameterInfo pInfo in myExtension.method.GetParameters())
                                {
                                    Type myType = Type.GetType(pInfo.ParameterType.ToString());
                                    methodParams[(i)] = Convert.ChangeType(paras[i + 4], myType);
                                    i++;
                                }
    
                                //Invoke with methodParams
                                //response = myMethod.method.Invoke(obj, BindingFlags.Public | BindingFlags.Instance, bBinder, methodParams, System.Globalization.CultureInfo.CurrentCulture);
                                response = myExtension.method.Invoke(obj, methodParams);
                            }
    
                            /*TODO - SOMETHING ALITTLE BETTER THEN ONLY CHECK FOR XPATHNODEITERATOR OR ELSE do ToString() */
                            if (response != null)
                            {
                                switch (myExtension.method.ReturnType.ToString())
                                {
                                    case "System.Xml.XPath.XPathNodeIterator":
                                        return ((System.Xml.XPath.XPathNodeIterator)response).Current.OuterXml;
                                    case "System.Xml.Linq.XDocument":
                                        return response.ToString();
                                    case "System.Xml.XmlDocument":
                                        XmlDocument xmlDoc = (XmlDocument)response;
                                        StringWriter sw = new StringWriter();
                                        XmlTextWriter xw = new XmlTextWriter(sw);
                                        xmlDoc.WriteTo(xw);
                                        return sw.ToString();
                                    default:
                                        string strResponse = ((string)response.ToString());
    
                                        if (myExtension.returnXML)
                                        {
                                            //do a quick "is this html?" check... if it is add CDATA... 
                                            if (strResponse.Contains("<") || strResponse.Contains(">"))
                                                strResponse = "<![CDATA[" + strResponse + "]]>";
                                            return "<value>" + strResponse + "</value>";
                                        }
                                        else
                                        {
                                            HttpContext.Current.Response.ContentType = "text/html";
                                            return strResponse;
                                        }
                                }
                            }
                            else
                            {
                                if (myExtension.returnXML)
                                    return "<error>Null value returned</error>";
                                else
                                    return string.Empty;
                            }
    
    
    
                        }
                    }
                }
    
                catch (Exception ex)
                {
                    //Overall exception handling... 
                    return "<error><![CDATA[MESSAGE:\n" + ex.Message + "\n\nSTACKTRACE:\n" + ex.StackTrace + "\n\nINNEREXCEPTION:\n" + ex.InnerException + "]]></error>";
                }
    
            }
    
    
        }
    
        // a temp handler used to force the SessionStateModule to load session state
        public class MyHttpHandler : IHttpHandler, IRequiresSessionState
        {
            internal readonly IHttpHandler OriginalHandler;
    
            public MyHttpHandler(IHttpHandler originalHandler)
            {
                OriginalHandler = originalHandler;
            }
    
            public void ProcessRequest(HttpContext context)
            {
                // do not worry, ProcessRequest() will not be called, but let's be safe
                throw new InvalidOperationException("MyHttpHandler cannot process requests.");
            }
    
            public bool IsReusable
            {
                // IsReusable must be set to false since class has a member!
                get { return false; }
            }
        }
    }
            #endregion

    Problem is, I don't quite know how to add this to my web.config to get this to call instead of the regular handler (which is what keeps happening). In the example given, it basically just had me remove the ,umbraco from the:

               <add name="umbracoBaseRequestModule" type="umbraco.presentation.umbracobase.requestModule"/>
    
  • Martin Lingstuyl 202 posts 379 karma points
    Dec 21, 2010 @ 17:22
    Martin Lingstuyl
    1

    Would that be just like this: type="BaseExtensions.requestModule"

     

     

     

  • Chad Rosenthal 272 posts 474 karma points
    Dec 21, 2010 @ 17:47
    Chad Rosenthal
    0

    Yes. I had to use some other code, but that was my exact problem.

    -C

     

  • Martin Lingstuyl 202 posts 379 karma points
    Dec 22, 2010 @ 00:11
    Martin Lingstuyl
    0

    So did you get it to work?

    I think you might also be able to add multiple types, like the code below (but i didnt trie it)

    I tried compiling your code, but it didnt work with me either. (though I didnt trie this here below)

     

    type="umbraco.presentation.umbracobase.requestModule, BaseExtensions.requestModule"
  • Chad Rosenthal 272 posts 474 karma points
    Dec 22, 2010 @ 00:12
    Chad Rosenthal
    0

    Yes. Got it to work. The problem was that I needed to replace the umbraco.presentation.umbracobase.requestModule with the entirely new module.

    -C

     

  • Martin Lingstuyl 202 posts 379 karma points
    Dec 22, 2010 @ 00:16
    Martin Lingstuyl
    0

    Really? I tried that, but it didnt work for me.

    So the code you wrote is a precise replacement for the original handler?

    Did you change anything before you got it to work? Otherwise you could mark this thread as solved.

    I might trie it again, but last time it didnt work.

     

     

  • Chad Rosenthal 272 posts 474 karma points
    Dec 22, 2010 @ 04:15
    Chad Rosenthal
    0

    Sorry, I mentioned that I had to use other code. This is the code for Umbraco 4.6 and I couldn't get it to work in 4.5.2. (I didn't try that hard though).

    I used this code: http://our.umbraco.org/forum/developers/api-questions/7973-MemberGetCurrentMember()-in-base

    I believe this thread has also been marked as solved.

Please Sign in or register to post replies

Write your reply to:

Draft