Thursday, September 22, 2011

How to compress JSON in IIS7

What you have to do is just add couple of record into applicationHost.config file:



<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" dynamicCompressionLevel="9" />
  <dynamicTypes>
    <add mimeType="text/*" enabled="true" />
    <add mimeType="message/*" enabled="true" />
    <add mimeType="application/x-javascript" enabled="true" />
    <add mimeType="application/json" enabled="true" />
    <add mimeType="application/json; charset=utf-8" enabled="true" />
    <add mimeType="*/*" enabled="false" />
  </dynamicTypes>
  <staticTypes>
    <add mimeType="text/*" enabled="true" />
    <add mimeType="message/*" enabled="true" />
    <add mimeType="application/x-javascript" enabled="true" />
    <add mimeType="application/atom+xml" enabled="true" />
    <add mimeType="application/xaml+xml" enabled="true" />
    <add mimeType="*/*" enabled="false" />
  </staticTypes>
</httpCompression>





















Wednesday, March 23, 2011

Releasing Excel after using Interop

Some time ago, I wrote a simple application to fill in and write on disk an Excel spreadsheet. Something like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using System.Net;
using System.IO;

namespace ExcelInterop
{
class Program
{
static void Main(string[] args)
{
Application oXL = null;
_Workbook oWB = null;
Workbooks oWBs = null;
_Worksheet oSheet = null;
Range oRange = null;

oXL = new Application();
oXL.Visible = false;
oXL.DisplayAlerts = false;

oWBs = oXL.Workbooks;

oWB = oWBs.Add(1);

oSheet = oWB.ActiveSheet;

oRange = oSheet.Cells[1,1];
oRange.Value = "Test";

oWB.SaveAs(@"C:\Temp\Test.xls", XlFileFormat.xlWorkbookNormal,
null, null, false, false, XlSaveAsAccessMode.xlShared,
false, false, null, null, null);

Console.WriteLine("Before cleanup.");
Console.ReadKey(false);

oWB.Close();
oXL.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject(oRange);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWBs);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);

Console.WriteLine("After cleanup.");
Console.ReadKey(false);
}
}
}

Although the program worked as expected, I encountered an annoying problem. The Excel application kept running even after releasing all Interop objects. After some investigation, I realized that the problem was caused by the following two lines of code:

oRange = oSheet.Cells[1,1];
oRange.Value = "Test"

If I comment them out, then after the cleanup, the Excel application will disappear from the list of running processes. But obviously, I needed to set the right value into the cell. So after some Googling, I ended up with the following alternative:

oRange = oSheet.Cells;
oRange.set_Item(1, 1, "Test");

This solution works perfectly, and releases the Excel application after clean up.

Monday, January 24, 2011

Simple WCF web service to receive parameter from HTTP POST request body

One week ago I tried to find a simple example how to build in Visual Studio 2010 WCF web service to receive parameter from HTTP POST request body. I found a lot of useful hints but not the complete sample. As I finally managed to compile my own solution, I'd like to share it.

1. Create a new project EchoService in Visual Studio based on "WCF Service Library" template.



2. Go to the project properties and change target framework to ".NET Framework 4".



3. Open App.config file and do the following changes:

- change base address to http://localhost:8000/
- replace endpoint section to

<endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="EchoService.IService1">

- add the following code under behaviors section:

<endpointBehaviors>
<behavior name="webBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>

4. Open IService1.cs file and replace it's content with the following code:
using System;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.IO;

namespace EchoService
{
[ServiceContract]
public interface IService1
{
[WebInvoke(UriTemplate = "echo")]
Stream HandleMessage(Stream request);
}
}

5. Open Service1.cs file and replace it's content with the following code:
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.IO;
using System.ServiceModel.Web;

namespace EchoService
{
public class Service1 : IService1
{
public Stream HandleMessage(Stream request)
{
StreamReader reader = new StreamReader(request);
string text = "EchoServer received: " + reader.ReadToEnd();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
MemoryStream ms = new MemoryStream(encoding.GetBytes(text));
WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
return ms;
}
}
}

6. Start debugging. If everything OK then Visual Studio starts WCF Test Client. Now you can open you favorite test tool (I use Fiddler) and send a post request to http://localhost:8000/echo.

7. In my case I sent a word "test" as request and received back "EchoServer received: test".

Enjoy.

Monday, January 10, 2011

How C# new dynamic type can simplify access to late bound COM object

A couple of years ago I’ve got an interesting task. I had to develop a public web service which utilized internally a third-party COM object. Sounds easy, the concept of COM Interop exists in .NET since the first release, so I didn’t expect any difficulties on my way.

Just to be more specific let’s say we have a very simple VB6 COM object "MyProject.MyClass" having a single method Add, taking two Integer parameters and returning a sum of them:

Public Function Add(first As Integer, second As Integer) As Integer
Add = first + second
End Function


I’ve started a new Visual Studio project, added a reference to the COM object and wrote the following code:

using System;
namespace ComTest
{
class Program
{
static void Main(string[] args)
{
MyProject.MyClass comObject = new MyProject.MyClass();
short sum = comObject.Add(1,2);
Console.Out.WriteLine("Early binding. Sum = " + sum);
Console.ReadLine();
}
}
}


It worked. But after some time I realized that the third-party COM object is updated on nearly monthly basis. And the COM object has been probably developed in VB6 with no version compatibility settings, resulting in constantly changing GUIDs even when the interface signatures haven't changed. As a result my program started to crash showing the following message:

An unhandled exception of type 'System.InvalidCastException' occurred in ComTest.exe

I had two options: either to recompile my web service each time I receive a new COM object or to use late binding. Obviously I went to the last option.
My C# code looked like this:

using System;
using System.Reflection;

namespace ComTest
{
class Program
{
static void Main(string[] args)
{
System.Type objType = System.Type.GetTypeFromProgID("MyProject.MyClass");
object comObject = System.Activator.CreateInstance(objType);

object[] oParms = new Object[] { 1, 2 };
short sum = (short)objType.InvokeMember(
"Add", BindingFlags.InvokeMethod, null, comObject, oParms);
Console.Out.WriteLine(sum);
Console.ReadLine();
}
}
}


It worked, but imaging if you have not just one method in COM object but plenty of them. Building every time a parameter list and calling InvokeMember is not the most pleasant way to spend your time in the office. And there was no other option till Visual C# 2010. Thank to new dynamic type it is possible now to declare an object of type which bypasses static type checking. At compile time, an element that is typed as dynamic is assumed to support any operation. Therefore, we can write the following code now:

using System;
using System.Reflection;

namespace ComTest
{
class Program
{
static void Main(string[] args)
{
System.Type objType = System.Type.GetTypeFromProgID("MyProject.MyClass");
dynamic comObject = System.Activator.CreateInstance(objType);

short sum = comObject.add(1, 2);
Console.Out.WriteLine("Late binding with dynammic type. Sum = " + sum);
Console.ReadLine();
}
}
}


So we are using now the same method signatures as in first example without needs to use a call to InvokeMember. However, if the method signature is not valid, errors are caught at run time. How will it help me? Very simple. First I start developing my application by adding a reference to the COM object. It's so easy to use .NET wrappers, generated for you by Visual Studio. When I an almost ready to deploy, I remove the reference and use GetTypeFromProgID instead.

That's it.

Friday, January 7, 2011

Visual Studio: Show active file in solution explorer

Just found a very useful VS feature in Ronald Wilda's blog:

I copy the solution here in case he decide to delete it.

One of the most annoying thing about Visual Studio default settings is the fact that the Solution Explorer doesn’t track what files you are currently looking at. Alot of developers thought this was the only way, and had to bear the pain of flicking through the Solution Explorer while scratching their head to figure out ‘where the hell I put this file?’.

Some have found a work around by using Visual Studio plugin like VS File Finder and Resharper (Ctrl + Shift + T / Resharper_GoToFile). While others found right clicking on the tab – open containing folder to be helpful enough.

There is actually a setting in Visual Studio that does this automatically.

Tools – Options – Projects and Solutions – Track Active Item in Solution Explorer

Just tick the box..and you’re all set!

Thursday, October 7, 2010

How to show history for Firefox

1. In Firefox go to URL: about:config

2. Set signed.applets.codebase_principal_support value to true

3. Use the following fragment in Java Script:

function getHistory()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
var list = "";
for (i = 0; i< self.history.length; i++)
{
list = list + self.history[i] + '\n';
}
return list;
}

Wednesday, July 1, 2009

I've passed Exam 70-503 TS: Microsoft .NET Framework 3.5 - Windows Communication Foundation Application Development today

Today I've passed exam 70-503 TS: Microsoft .NET Framework 3.5 – Windows Communication Foundation Application Development. I prepared for exam mostly by studing the MCTS Self-Paced Training Kit (Exam 70-503): Microsoft® .NET Framework 3.0—Windows Communication Foundation (I have to note - it is not the best book).