Tuesday, December 24, 2013

Using HTTP Modules


HTTP Modules are assemblies which can be called during every http request.

This comes in very handy when there is a need to intercept every request that comes into the Web application.

This is basically a simple class that is derived from IHttpModule interface.

Here is the sample code. This will be compiled to a DLL file.


public class MyClass : IHttpModule
{
        /// <summary>
        /// This is the disposing function.
        /// </summary>
        void IHttpModule.Dispose()
        {

        }

        /// <summary>
        /// This is the initialization function.
        /// </summary>
        /// <param name="context">This is the httpApplication context.</param>
        void IHttpModule.Init(HttpApplication httpApp)
        {
            httpApp.BeginRequest += new EventHandler(context_BeginRequest);
        }

        /// <summary>
        /// This is where the Begin Request Action is taking place.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication httpApp = (HttpApplication)sender;
            RequestManipulation(httpApp);
        }

        /// <summary>
        /// This is the core function which tries to alter the request.
        /// </summary>
        private void RequestManipulation(HttpApplication httpApp)
        {
                    AlterNameValueCollection(httpApp);
        }

       /// <summary>
        /// Writes details of the Form NameValueCollection in the REQUEST object.
        /// </summary>
        /// <param name="httpApp">This is the input HttpApplication context from which the request header details will be written out.</param>
        private void AlterNameValueCollection(HttpApplication httpApp)
        {
            NameValueCollection postInfo = httpApp.Request.Form;
            System.Reflection.PropertyInfo prop = httpApp.Request.Form.GetType().GetProperty("IsReadOnly", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            // Set the property false (writable)
            prop.SetValue(httpApp.Request.Form, false, null);
            foreach (String eachKey in postInfo.AllKeys)
            {
                string towrite = string.Format("Key : {0} - Value : {1}", eachKey, httpApp.Request.Form[eachKey]);
                Helper.WriteinFile(towrite);
                if (eachKey == "AuthorName")
                {
                    Helper.WriteinFile("Before Changing AuthorName value....");
                    string oldValue = httpApp.Request.Form[eachKey].ToString();
                    httpApp.Request.Form[eachKey] = "MyClass Success. The old value '" + oldValue + "' was modified by the MyClass dll." ;
                    Helper.WriteinFile("Just now changed the AuthorName value.");
                }
            }
        }
}

After this code is compiled, copy the DLL file to the "bin" folder of the ASP.NET application on which the requests should be intercepted.

This DLL will be loaded into memory by using the following entries in the "Web.Config" file.

  <system.webServer>
    <modules>
      <add name="MyClass" type="MyNamespace.MyClass, MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=77ced88f9fdf21cb" preCondition="managedHandler,runtimeVersionv4.0" />
    </modules>
  </system.webServer>
 
This DLL can also be installed in the "Global Assembly Cache" and the above entries should load it automatically.

Hope this blog helps.

Happy coding !

Cheers
Adam
 
 




 
 

Friday, November 29, 2013

Getting ASP.NET page values from Silverlight


There was a need to obtain values from the ASP.NET page to Silverlight application.

This is the function that can get the value.

private string GetHtmlElementValue(string htmlElementId)
{
   string togoElementValue = "";
   HtmlDocument doc = HtmlPage.Document;
   if (doc == null)
   {
     MessageBox.Show("Html Document is null.","Error", MessageBoxButton.OK);
      return togoElementValue;
   }
   HtmlElement elm = doc.GetElementById(htmlElementId);
   if (elm == null)
   {
     MessageBox.Show("Html Element " + htmlElementId + " is null.", "Error", MessageBoxButton.OK);
     return togoElementValue;
   }
     togoElementValue = elm.GetAttribute("value");
     return togoElementValue;
}

This is how the function should be called.

GetHtmlElementValue("AuthenticationTypeField");

This will come in handy when we need to pass the information from ASP.NET page to Silverlight Application.

Hope this helps.

Cheers
Adam



 
 
 

Monday, October 28, 2013

Log File not written during scheduled task execution in Python Script

I wrote a python script to perform a scheduled job. I was also logging few information in a simple text file. But for some reason, nothing was written in the log file.

After doing some research, I found that, when setting up the scheduled task, I must fill in the "Start In" folder location. Only when this value is set, the python script can write the log file correctly.

Hope this helps !

Happy Coding.

Wednesday, September 25, 2013

Intercept calls coming to a Web Application in IIS Server



It was required to intercept all the calls coming into a particular web application on the IIS Server and identify the contents in the request. We ended up writing a class derived from “IHttpModule" interface.
Here are some tips on how to create and install it on the IIS server.
  • Creating the class is a simple task. Just derive the class from the interface “IHttpModule". Implement the interface as shown below.

public class ServerIntercept : IHttpModule
{
      public void Dispose()
       {
       }
       public void Init(HttpApplication context)
       {
        context.BeginRequest += context_BeginRequest;
        }
        void context_BeginRequest(object sender, EventArgs e)
        {
            // Add all code here
        }
}

  • Make sure the DLL is signed with strong name key
  • Copy this DLL to the server and use GAC utility to register this on the server.  If it is .NET 2 framework it is a different utility and if it is .NET 4 framework it is a different utility. Use the correct utility to register.
  • Add the entries to the Web.Config file of the application. This file may be read-only. Make sure the entries are being saved properly. A sample is shown below.
<configuration>
<system.webServer>
<modules>
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
</modules>
</system.webServer>
</configuration>

 The type in the above example is the class name with namespace and the DLL file name. The public key token value can be obtained from the GAC utility.
  • Reset IIS. Then open the IIS manager. Go to the application and look into the “Modules” section. The newly installed module must be present and now the application is ready to intercept all the calls coming to it.

Happy coding!

Monday, August 26, 2013

Java heap space – ArcGIS Server Error


Recently when we were doing some spatial ArcGIS query using ArcGIS REST endpoint, we ran into some issues.
We turned on the server logs and started to monitor it. We found the following error entries in the log files.

Exception caught while processing request. Java heap space
Internal Server Error. Error handling service request : java.lang.OutOfMemoryError: Java heap space

com.esri.discovery.DiscoveryException: Error handling service request : java.lang.OutOfMemoryError: Java heap space

After several hours of debugging, we discovered one crucial problem.
In our published MXD file, we had few GIS Featureclass Layers from ArcSDE and also standalone ArcSDE tables.  There was a JOIN established between the GIS Featureclass Layer and standalone table. We realized that the GIS Featureclass layer was not versioned, but the ArcSDE standalone table was versioned. We removed the versioning from the standalone table and all started to work as expected.

It was surprising to see this kind of behavior. I am documenting this here so that it might help someone.
Cheers
Anand

Saturday, July 13, 2013

Storing and Retreiving Data from a Web Server using WCF Web Service


In one of my Silverlight projects, there was a need to store some data on the server and get it back as needed. I wrote a simple WCF Web Service to do this. This service will take in a string and write it on the server on a file called "AppSettings.xml".

The web service function "GetStoredDataFromServer()" will get the stored data in string format from the server.

The web service function "SaveDataOnServer(string datatoSave)" will store the data on the server.

When deploying this service on the IIS server, make sure to provide write permission for the IIS_IUSRS account to the file "AppSettings.xml". This is required because the anonymous user must be able to save the information on the file "AppSettings.xml".


 Here is the code.

 This code needs to go on the IService.cs.

    [ServiceContract]

    public interface IStoreService

    {

        [OperationContract]

        string GetStoredDataFromServer();

 

        [OperationContract]

        string SaveDataOnServer(string datatoSave);

    }


This code needs to go on the Service.svc.cs file.

   public class StoreDataService : IStoreService

    {

        public string GetStoredDataFromServer()

        {

            string togoMessage = "";

            string fileName = AppDomain.CurrentDomain.BaseDirectory + "AppSettings.xml" ;

            if (File.Exists(fileName) == false)

            {

                try

                {

                    StreamWriter sw = new StreamWriter(fileName);

                    sw.WriteLine("");

                    sw.Close();

                }

                catch (Exception ex)

                {

                    togoMessage = "Error : " + ex.ToString();

                    return togoMessage;

                }

            }

            else

            {

                StreamReader sr = new StreamReader(fileName);

                togoMessage = sr.ReadToEnd();

                sr.Close();

            }

            return togoMessage;

        }

 

        public string SaveDataOnServer(string datatoSave)

        {

            string togoMessage = "";

            string fileName = AppDomain.CurrentDomain.BaseDirectory + "AppSettings.xml";

            try

            {

                StreamWriter sw = new StreamWriter(fileName);

                sw.WriteLine(datatoSave);

                sw.Close();

            }

            catch (Exception ex)

            {

                togoMessage = "Error : " + ex.ToString();

                return togoMessage;

            }

            return togoMessage;

        }

    }

 Happy Coding !

All Blogs so far ...