Angel Hernández

Assembler Language in .NET and some other ideas

Hi Community,

This post is about something not very recent in .NET and it’s been available for a while, but the first time I read about it I couldn’t blog it because I didn’t have a blog back then Stick out tongue and since I’m currently reading this book once again "The art of assembly language" (I think that I’m reading it for the third time… It just contains too much information) so I thought it’s worthy to mention it. Even when .NET is  managed code, in the end the CPU understands  machine code which can be represented through  assembler language. This happens the same with the rest of other languages (managed and non-managed). Back in  2001, someone had the brilliant idea of doing  ASP.NET with  assembler language.  The article can be found  here and below a sample page is depicted

The few things I learned about assembler language was back in 1995, thanks to my mate Virginia when she was about to earn her degree in Bsc. Systems Engineering and I was a freshman in Uni. I used to spend a lot of time with Microsoft C/C++ 7.0 (MFC 1.0 was bundled in it) and I thought it was cool to place inline code inside  __asm, at the same time I was learning VB 4.0 and in my spare time I played  Heretic and MK II... I remember my mom calling me to go and have lunch Stick out tongue *sigh* What a wonderful time!!!... There’s one thing I’ve been trying to keep from that time and throughout the years and it’s been like a golden rule: "whatever you do, do it with passion and… there’s no a better way to learn something new than by playing with it”  and that’s probably why I never get bored of PCs, technology and related stuff.

Changing of topics, some days ago one of our customers had a new requirement “I’d like to detect when an active session is about to expire and store the existing cart in CRM", this is something very easy and straightforward to do in ASP.NET, where I can put some code in the Global.asax and intercept the Session_End event but what I’m talking about is a SharePoint based solution with form based authentication enabled and as we all MUST know by now, SharePoint supports this authentication scheme since  version 2007, because it has always relied on  NTLM and Kerberos.  Anyways I had a couple of approaches which I mention below: 

  • Every single SharePoint application is an instance of SPHttpApplication which in turn inherits from HttpApplication, so I said  "Nah... this is a piece of cake", I just need to modify the Global.asax and write some inline code to handle Session_End  but it doesn’t work Sad so I thought about creating a new project and explicit inherit from SPHttpApplication but it doesn’t work either…  So I gave it a try to another alternative…

  • Write an HttpModule which contains a singleton and at the same time it keeps a data structure updated and in sync by a  critical section at the moment of a session timing out, code is shown below
  • using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.ApplicationRuntime;
    using System.IO;
    using Microsoft.SharePoint.Security;
    using System.Runtime;
    using System.Runtime.InteropServices;
    using System.Web.SessionState;
     
     
    namespace Demo {
        public class MyCustomApplication : IHttpModule {
            #region IHttpModule Members
            private SyncedInfo _synced = null;
            private GCHandle? _allocatedMem = null;
     
            private GCHandle? AllocatedMemory {
                get {
                    return _allocatedMem;
                }
                set {
                    _allocatedMem = value;
                }
            }
     
            private SyncedInfo Singleton {
                get {
                    return _synced;
                }
                set {
                    _synced = value;
                }
            }
     
            public void Dispose() {
                if (AllocatedMemory != null) {
                    AllocatedMemory.Value.Free();
                }
            }
     
            public void Init(HttpApplication context) {
                if (Singleton == null) {
                    Singleton = new SyncedInfo(context.Modules["Session"]);
                    AllocatedMemory = GCHandle.Alloc(Singleton);
                }
            }
            #endregion
        }
     
        [Serializable]
        public class SyncedInfo {
            protected SessionStateModule _sessionModule;
            protected HttpContext _currentContext = HttpContext.Current;
     
            public SyncedInfo(IHttpModule context) {
                _sessionModule = (SessionStateModule)context;
                _currentContext.Application["UserData"] = new Dictionary<string, string>();
                _sessionModule.Start += Session_Start;
                _sessionModule.End += Session_End;
            }
     
            public bool Push(string customer, string selectedData) {
                bool retval = false;
                object userData = _currentContext.Application["UserData"];
     
                try {
                    lock (userData) {
                        if (!((Dictionary<string, string>)userData).ContainsKey(customer)) {
                            ((Dictionary<string, string>)userData).Add(customer, selectedData);
                        } else {
                            ((Dictionary<string, string>)userData)[customer] = selectedData;
                        }
                        retval = true;
                    }
                } catch { } // Swallow the exception
                return retval;
            }
     
            public KeyValuePair<string, string>? Pop(string customer) {
                KeyValuePair<string, string>? retval = null;
                object userData = _currentContext.Application["UserData"];
     
                try {
                    lock (userData) {
                        if (((Dictionary<string, string>)userData).ContainsKey(customer)) {
                            retval = new KeyValuePair<string, string>(customer, ((Dictionary<string, string>)userData)[customer]);
                            ((Dictionary<string, string>)userData).Remove(customer);
                        }
                    }
                } catch { retval = null; } // Swallow the exception
                return retval;
            }
     
            private void Session_End(object sender, EventArgs e) {
                // Serialize data here (Pop)
     
                SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(delegate() {
                    WriteActivity(false);
                }));
     
            }
     
            private void Session_Start(object sender, EventArgs e) {
                // Push should be call from the App (UI)
     
                SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(delegate() {
                    WriteActivity(true);
                }));
            }
     
            private void WriteActivity(bool state) {
                string fileName = @"c:\log.txt";
     
                try {
                    using (StreamWriter logWriter = (!File.Exists(fileName) ? File.CreateText(fileName) : File.AppendText(fileName))) {
                        logWriter.WriteLine(string.Format("Session {0} at {1}", new object[] { (state ? "Started" : "Ended"), DateTime.Now }));
                        logWriter.Flush();
                        logWriter.Close();
                    }
                } catch { } // Swallow exception
            }
        }
    }

This approach should work, it does as a matter of fact, when Session_Start is triggered but it doesn’t fire when the session expires and in my humble opinion this is quite annoying because  SharePoint is taking away from me something that ASP.NET provides, this is valid when security relies on Windows and “a valid ticket” is always available, but what about form based authentication?

In conclusion, I can do ASP.NET with assembler language (according to the previously mentioned article) but I can’t intercept any event related to a  session timing out in SharePoint Sad  How cool is that!!!!

Regards,

Angel

Leave a Comment

(required) 

(required) 

(optional)

(required)