Thursday, April 5, 2012

VSIX project manifest file

Problem: When you try to open new VSIX project in visual studio it will open it in designer. No matter how many time you specify that you want the file to be opened in XML it will still open it in designer view.

Impact: Editing the file in designer view is cumbersome. XML editing is way more easy to understand and edit.

Solution:
The only way to force the change is to manually modify the .csproj as follows:
<ItemGroup>
  <None Include="source.extension.vsixmanifest">
    <SubType>Code</SubType>
  </None>
</ItemGroup>

"Webservice method name not valid"

Problem: Lets say calling web service from a clients method A it works fine, but when we change the name of the method A to B on client it returns and error "Web service method name not valid"

Impact: Limitation of not able to change the method name after the web service reference has been created.

Solution:
Let's suppose you create a proxy for a webservice. Assume that you KNOW that only certain (signed) code should use your proxy, then, it's only natural that you add a StrongNameIdentityPermission to its declaration:
[StrongNameIdentityPermission(SecurityAction.LinkDemand,PublicKey="your_trusted_key")] 
public class MyWebService : SoapHttpClientProtocol 
When you try to call any method with such a proxy, you'll get a pretty strange error:
[your_webmethod] Web Service method name is not valid. It turns out to be that because of the permission, the internal classes that reflect your type can't get the methods in the class. And when the method to call is looked-up in an internal list and not found, that exception is thrown. However, there's nothing wrong with the method name. The method that throws the exception is SoapHttpClientProtocol.BeforeSerialize, which performs the lookup against a private instance of the type SoapClientType.
The proxy initialization code involves the following steps before that failure:
  1. Proxy constructor initializes a SoapClientType: it passes the current proxy type so that it is reflected to get the web methods.
  2. SoapClientType constructor calls LogicalMethodInfo.Create passing all the proxy public methods, retrieved using Type.GetMethods(BindingFlags.Instance | BindingFlags.Public). This method checks for asynchronous methods and does some other trivial work.
  3. SoapClientType constructor calls SoapReflector.ReflectMethod with each LogicalMethodInfo constructed in the previous step.
I've tracked down the bug by making extensive use of reflection. I've executed each of the methods above, which I identified as the hot-spots for the bug, using trusted code (the assembly signed with the key required by the proxy) and then with untrusted code, which will always be the case for System.Web.Services.dll. Here are the results:
  • SoapClientType constructor: it works as expected, but its internal list of methods available is empty when the constructor is run without the required public key:
    Type t = ReflexHelper.LoadPrivateType(
        "System.Web.Services.Protocols.SoapClientType, System.Web.Services");
    object sct = Activator.CreateInstance(
          t, BindingFlags.Instance | BindingFlags.NonPublic, null, 
            new object[] { typeof(Messaging.MessagingWebService) }, null, null);
    FieldInfo fi = t.GetField("methods", 
          BindingFlags.Instance | BindingFlags.NonPublic);
    Hashtable methods = fi.GetValue(sct) as Hashtable;
    Note that I access a private field called methods which contains the list loaded by the constructor code.
    I went deeper as the methods hastable I got was always empty when I run the unsigned version. The following method is called inside this constructor, and is the next hot-spot.
  • LogicalMethodInfo.Create: it correctly returns the list of methods irrespective of the signature of the calling code. Therefore, the bug isn't here:
    MethodInfo[] mis = typeof(MyWebService).GetMethods(
            BindingFlags.Instance | BindingFlags.Public);
    LogicalMethodInfo[] li = LogicalMethodInfo.Create(mis, LogicalMethodTypes.Sync);
    So I went further to the call on SoapReflector.
  • SoapReflector.ReflectMethod: I couldn't go any further than this because the dependecies are too deep with other private and internal types. However, this method IS the one to blame for the strange error. It fails to reflect the methods on the type because of the StrongNameIdentityPermission, but does not throw any exceptions, thus swallowing the fact that it's a security permission that is failing, instead of the unrelated exception thrown at the moment we actually perform the WebMethod call on the proxy.
    Here's the code that proves it:
    ArrayList list = new ArrayList();
    t = ReflexHelper.LoadPrivateType(
            "System.Web.Services.Protocols.SoapReflector, System.Web.Services");
    MethodInfo reflect = t.GetMethod("ReflectMethod", 
            BindingFlags.Static | BindingFlags.NonPublic);
    
    foreach (LogicalMethodInfo i in li)
    {
        //This always returns null if we're not signed with the key required 
        //(always the case for System.Web.Services.dll)
        object m = reflect.Invoke(
            null, BindingFlags.Static | BindingFlags.NonPublic, null, 
            new object[] { 
                i, true, new XmlReflectionImporter(), 
                new SoapReflectionImporter(), "default-namespace" }, 
                null);
        if (m != null)
            list.Add(m);
    }
    
    Console.WriteLine(list.Count);
    Signing this test console project with the public key required by the proxy results in the correct list of webmethods being loaded into the list object. The object returned by the ReflectMethod is checked in the SoapClientType constructor, but only for non-null returns. If the returned object is null, nothing is done and the internal list of available methods will silently remain empty.
So, how do you protect the class now? Well, put your demand in the class constructor instead of the definition, and nobody will be able to instantiate your proxy unless it's signed with the trusted key. What's more, it makes the code more performant because it avoids the check for each member used (as is the case for the class-level demand).

Parsing valid JSON data

Problem: When sending the request to the server and the response returned by the server is in JSON format and trying to parse the JSON object results into string data type rather than object data type.

Response from the server..JSON format

{"items":[            
  {
   "src": "1.jpg",
   "id": "83",
   "gallery_id": "30",
   "username": "admin"
  }]
}

Impact: Cannot store the data as an object data type.

Solution: The above JSON string should be concatenated with the brackets in order to 
be a valid JSON data. 

({"items":[            
  {
   "src": "1.jpg",
   "id": "83",
   "gallery_id": "30",
   "username": "admin"
  }]
})

C# - UI freezes when calling background worker

Problem: When the user tries to update a data grid on main window in background workers progress changed method the UI freezes.

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
        DataTable oData = null; 
        SetDataSource(oData);
    }

    private void SetDataSource(object value) {
        dataGridView1.DataSource = value;
    }
 
An exception is thrown Cross thread operation.
 
 
 
 
Imapact: The user application crashes when populating data in grid view.
 
 
Solution: When calling the UI elements that were drawn on other thread than the 
calling thread a cross thread process exception is thrown.
 
We need to invoke the UI element to be drawn with the calling thread.
 
 
private delegate void SetDataSourceDelegate(object value);

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
        DataTable oData = null; 
        if (dataGridView1.InvokeRequired) {
            dataGridView1.Invoke(new SetDataSourceDelegate(SetDataSource), new Object[] {oData});
        }else{
            SetDataSource(oData); 
        }
    }

    private void SetDataSource(object value) {
        dataGridView1.DataSource = value;
    }
 

C# .NET - Catching threadpool thread exceptions

Problem: You receive a compiler error of exception was unhandled when trying to catch exception in a method called by a thread in main thread.



Impact: Developer cannot debug the application and catch the exception from a thread running in main thread. The application will crash if any exception is generated in thread from a thread pool.



Solution: We need to understand why this compiler error is generated when trying to catch exception from a method called by a thread from a thread pool. The answer is simple "They are different threads". Confused???
Ok let us put it this way..
Imagine main method thread as a highway (1) and one road branched out from Highway (1) which is the thread t from thread pool as Highway (2).
* If a car going on highway (1) crashes than the traffic will be blocked and Highway (1) will know about it.
* If a car going on highway (2) crashes than the traffic will be blocked and Highway (2) will know about it.
But how can Highway (2) inform Highway (1) that a car has crashed on Highway (2) unless there is another entry point along the Highway (1) into Highway (2). Both the Highways has there individual traffic which goes on without affecting each other.
The same way an exception thrown on a thread from a thread pool wont be caught by the try - catch block of main thread.
We need to wrap the try - catch block around the thread delegate to make this work and catch the exception thrown.

class Program
    {
        static void Main(string[] args)
        {
            try
        {
            Thread t = new Thread(() =>
                {
                    try
                    {
                        exec();
                    }
                    catch (Exception ex)
                    {
                        System.Console.WriteLine("exception caught");
                        System.Console.ReadLine();

                    }
                }
                );              
            t.Start();

        }
        catch (Exception ex)
        {

        }
    }
    static void exec()
    {
        throw new NullReferenceException();
    }

       
    }