I'm having problems with GetCurrentMember() in /base - having run debugger, it seems that the HttpContext.Current.User is null even when my user is logged in.
Should this function work, or is the User part of the context loaded after the requestModules fire? I've also tried logging in the member via base, and this has the same issue?
Thanks Peter, but alas, no - I'm using 4.03.1 from codeplex svn branch and I see some comments in the code about not using getCookieValue("umbracoMemberId") in a few other places - my version of CurrentMemberId is looking for HttpContext.Current.User.IsAuthenticated before hitting the FormsAuthentication to get the User ID. I'm also running IIS7 on Vista, which is the only other thing I thought might affect it?
public static XPathNodeIterator data()
{
var currentMember = Member.GetCurrentMember();
if (currentMember != null)
{
XmlDocument mXml = new XmlDocument();
mXml.LoadXml(currentMember.ToXml(mXml, false).OuterXml);
XPathNavigator xp = mXml.CreateNavigator();
return xp.Select("/node");
}
else
return null;
}
The changes made no difference to the result. I have also tried both integrated and classic pipeline modes in IIS7. I'm going to try on IIS6 now, and will report back.
I have a solution for now anyway. I read http://msdn.microsoft.com/en-us/library/ms178473.aspx to remind myself of the request pipeline, and looking at the base requestModule, everything is happening on BeginRequest.
I created my own module, with the url parsing separated from the method invocation and it then works.
Module.PreRequestHandlerExecute = invoke the base method
As a solution, this make sense to me given the problem I'm experiencing - what doesn't make sense is the that yours works and mine doesn't? Do you think I should log an issue on codeplex and include my patch?
I'm having the same problem on my system, I'm using 4.0.3. GetCurrentMember returns null, and I don't know enough yet to seperate the url parsing from the method invocation... I wouldn't even know where to start with this :)
This seems to be a general issue with 4.0.3. I've implemented a new baseRequestModule like Chris described and its working fine now. (Thanks Chris, for the pointer.)
If added the code for others who are expriencing this issue. All you have to do is replace the standard umbracoBaseRequestModule in your web.config to something like:
using System.Data; using System.Text; using System.Text.RegularExpressions; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Reflection; using System.Collections.Specialized; using System.Xml; using umbraco; using umbraco.cms.businesslogic.member; using umbraco.presentation.umbracobase;
namespace Busker.Umbraco.BaseRest { public class buskerRequestModule : IHttpModule { #region IHttpModule Members public void Dispose() { }
public void Init(HttpApplication httpApp) { httpApp.BeginRequest += new EventHandler(OnBeginRequest); httpApp.PreRequestHandlerExecute += new EventHandler(PreRequestHandlerExecute); }
//remove extension and split the url string url = httpApp.Context.Request.RawUrl;
if (url.ToLower().StartsWith("/base/")) { if(url.ToLower().Contains(".aspx")) url = url.Substring(0, url.IndexOf(".aspx"));
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);
restExtension myExtension = (restExtension)httpApp.Context.Items["myExtension"]; if (myExtension != null) { if (myExtension.isAllowed) { httpApp.Response.Output.Write(invokeMethod(myExtension, urlArray)); } else { //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++; }
/*TODO - SOMETHING ALITTLE BETTER THEN ONLY CHECK FOR XPATHNODEITERATOR OR ELSE do ToString() */ if (response != null) { if (myExtension.method.ReturnType.ToString() == "System.Xml.XPath.XPathNodeIterator") return ((System.Xml.XPath.XPathNodeIterator)response).Current.OuterXml; else { 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 { //Error msg... return "<error>Null value returned</error>"; }
Do you know if this works in Umbraco 4.5.2? I made a class and followed your instructions, but when I try to step through the code, it never gets called.
This is probably something obvious, but I can figure it out. I want to access an active property on my member type for logged in users to display a message if there membership isn't active yet (the active property is a true/false property type;
var m = Member.GetCurrentMember(); Response.Write(m.getProperty("active").Value);
The code above returns me two Member objects, why would that be the case? The response.write displays "00", or "11" for active users?
Member.GetCurrentMember() in /base
Hi -
I'm having problems with GetCurrentMember() in /base - having run debugger, it seems that the HttpContext.Current.User is null even when my user is logged in.
Should this function work, or is the User part of the context loaded after the requestModules fire? I've also tried logging in the member via base, and this has the same issue?
Any suggestions?
Thanks,
Chris
Hi,
try this:
Worked for me so far.
Peter
Thanks Peter, but alas, no - I'm using 4.03.1 from codeplex svn branch and I see some comments in the code about not using getCookieValue("umbracoMemberId") in a few other places - my version of CurrentMemberId is looking for HttpContext.Current.User.IsAuthenticated before hitting the FormsAuthentication to get the User ID. I'm also running IIS7 on Vista, which is the only other thing I thought might affect it?
Does this happen on every page or just on your homepage?
You might want to try to add:
<remove name="FormsAuthentication" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
It happens when I call the base URL directory, and from any page.
http://localhost/base/account/data.aspx
The code is
The changes made no difference to the result. I have also tried both integrated and classic pipeline modes in IIS7. I'm going to try on IIS6 now, and will report back.
IIS6 also not working for me
This works just fine for me:
Hi Peter,
I have no idea why yours works and mine doesn't.
I have a solution for now anyway. I read http://msdn.microsoft.com/en-us/library/ms178473.aspx to remind myself of the request pipeline, and looking at the base requestModule, everything is happening on BeginRequest.
I created my own module, with the url parsing separated from the method invocation and it then works.
Module.BeginRequest = parseUrl + Create rest extenstion
Module.PreRequestHandlerExecute = invoke the base method
As a solution, this make sense to me given the problem I'm experiencing - what doesn't make sense is the that yours works and mine doesn't? Do you think I should log an issue on codeplex and include my patch?
Thanks for all your help,
Chris
Glad you found a way to make it work for you!
What came to mind, I tested my posted code against a 4.1 umbraco-install. I take it you're using 4.0.3, which could make a difference.
Other than that, I can't say much, because I don't know how the rest of your implementation looks like.
Perhaphs someone with a better insight in umbraco can shed a ligth on this.
Peter
I'm having the same problem on my system, I'm using 4.0.3. GetCurrentMember returns null, and I don't know enough yet to seperate the url parsing from the method invocation... I wouldn't even know where to start with this :)
Could you offer any advice on this?
Regards,
Johannes
This seems to be a general issue with 4.0.3. I've implemented a new baseRequestModule like Chris described and its working fine now. (Thanks Chris, for the pointer.)
The only remaining issue is that it work with directory urls and querystrings. But you can overcome this by adding the .aspx extension again, which is fine for my purposes. So instead of http://localhost/base/postings/my?page=1 you'll have to call it http://localhost/base/postings/my.aspx?page=1
If added the code for others who are expriencing this issue. All you have to do is replace the standard umbracoBaseRequestModule in your web.config to something like:
Cheers,
Karsten
Do you know if this works in Umbraco 4.5.2? I made a class and followed your instructions, but when I try to step through the code, it never gets called.
Thanks,
C
I've also tried adding the code from 4.6, but that doesn't seem to work either. Just can't seem to hit it.
Ah, my problem was that I needed to change the type to:
Busker.Umbraco.BaseRest.buskerRequestModule
Hi Guys,
This is probably something obvious, but I can figure it out. I want to access an active property on my member type for logged in users to display a message if there membership isn't active yet (the active property is a true/false property type;
var m = Member.GetCurrentMember();
Response.Write(m.getProperty("active").Value);
The code above returns me two Member objects, why would that be the case? The response.write displays "00", or "11" for active users?
Cheers
Chris
I have the same symptom in 4.7 with /base, however the member Id is retured.
So, as long as the CurrentMemberId is returned one can fetch the member using the member constructor which takes a member id.
Hope this helps,
Harald.
is working on a reply...