Notes from Daily Encounters with Technology RSS 2.0
 
# Sunday, January 08, 2012

Web.config transformations are a great but often overlooked feature introduced with ASP.NET 4.0. They provide a simple way to define a different configuration for Debug and Release builds of your project by only specifying the differences (typically only connection strings and similar settings) in a separate transformation file while keeping the core of the configuration file common and consequentially making it easier to manage.

Unfortunately files aren’t transformed until the web deployment package is created, i.e. they aren’t part of the core build process. This makes the transformations more difficult to use in some scenarios such as having a different configuration file for automated testing as a part of the build process.

Since the transformation is done by the TransformXml MSBuild task in Microsoft.Web.Publishing.Tasks.dll assembly there is a way to make this work by modifying the project file manually, though. Here is a snippet that I added to my project file (line break in the AssemblyFile added for readability only):

<UsingTask TaskName="TransformXml" 
           AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\
                         v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild">
    <MakeDir Directories="obj\$(Configuration)" 
             Condition="!Exists('obj\$(Configuration)')" />
    <TransformXml Source="Web.Config" 
                  Transform="Web.$(Configuration).config" 
                  Destination="obj\$(Configuration)\Web.config" 
                  StackTrace="true" 
                  Condition="Exists('Web.$(Configuration).config')" />
</Target>

As you can see the transformed configuration file is put inside the obj folder from where I copy it to the desired final location before running the tests. I find this a suitable spot for it unless you are precompiling views in your ASP.NET MVC project. A web.config file anywhere in obj folder brakes the build so you’ll have to put the file elsewhere or make sure you delete it before precompiling the views.

If you want to make this work on your build server without having Visual Studio installed on it, there is one more step remaining. The above mentioned assembly is not installed with .NET SDK meaning that you have to copy it there from your development machine. The file is located in the MSBuild extension folder, i.e. “C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\” by default.

Transformation files displayed under the original fileThis takes care of transforming web.config files during build. How about transforming app.config files and even other XML files in your projects? I guess it would be possible to use the same MSBuild task on them but no Visual Studio support for transforming those files would mean even more tempering with project files to make transformation files appear under the file they are used to transform.

This is where SlowCheetah – XML Transforms Visual Studio extension can help. After installing it you can define transformations for app.config the same way you are already doing it with web.config files. The transformation is part of the build process in this case, i.e. the transformed file is put in its usual spot in the build output folder (usually bin) instead of the original one. It couldn’t get any simpler.

As an added bonus the extension features support for previewing the results of the transformation: after right clicking the transformation file and selecting the Preview Transform command a diff window will open graphically showing the differences between the original and the transformed file. Of course this works with web.config transformations as well making the debugging of transformations much simpler. A good reason in itself to install this extension.

To avoid failed builds on your build server as well as with the other members of your team not having this extension installed it’s best that you copy the SlowCheetah MSBuild targets and the corresponding assembly containing the tasks to your solution directory and put it in source control. In this case you’ll again have to modify the project file to set the new path. Just search for the SlowCheetahTargets property definition and modify the path accordingly (line breaks added for readability):

<PropertyGroup>
    <SlowCheetahTargets Condition=" '$(SlowCheetahTargets)'=='' ">
        ..\_References\SlowCheetah\SlowCheetah.Transforms.targets
    </SlowCheetahTargets>
</PropertyGroup>

Are there any ways to make your life simpler by using configuration transformations in your projects?

Sunday, January 08, 2012 12:34:56 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | .NET | ASP.NET | Software | VisualStudio
# Monday, December 26, 2011

DateTime can be a tricky data type to deal with. Not only is there daylight saving time and different time zones to keep in mind but also the range and precision can vary in different systems. You are probably already aware of some differences between .NET framework’s DateTime structure in Transact-SQL’s datetime data type.

Most notable is certainly a different minimum value that can be expressed:

  • In .NET framework all values between January 1st 1 and December 31st 9999 are supported.
  • In Transact-SQL only values between January 1st 1753 and December 31st 9999 are supported.

This usually shouldn’t be a problem unless you are working with historic data. Setting proper minimum value in the user interface is not be a bad idea nevertheless.

You might not be aware of the difference in precision between these two data types, though. In some edge cases this can cause strange and unpredictable behavior. Let’s take a look at the following example (based on an issue that had me mystified for some time):

using (var context = new TestEntities())
{
    var task = context.Tasks.Single(t => t.Id == taskId);
    task.CompletedAt = DateTime.Now;
    timestamp = task.CompletedAt.Value;
    context.SaveChanges();
}

using (var context = new TestEntities())
{
    var task = context.Tasks.Single(t => t.Id == taskId);
    Assert.GreaterOrEqual(timestamp, task.CompletedAt);
}

The assertion in the above code will occasionally fail with a message similar to this one:

SampleTest has failed:
  Expected: greater than or equal to 2011-12-26 19:04:28.313
  But was:  2011-12-26 19:04:28.312

If you’re not familiar with entity framework, here’s what’s going on:

  • In the first code block a DateTime value is stored to the database.
  • In the second code block that same value is reloaded from the database.
  • The value from the database is compared with the one stored in a local variable the whole time.

The strange behavior is caused by the fact that milliseconds get rounded in the database: to increments of .000, .003, or .007 seconds, as it is stated in the documentation. The DateTime value can therefore be different when reloaded from the database, hence the occasional failed assertion. While the problem might be fairly obvious in the simplified example above, it can be much more difficult to pinpoint in a larger chunk of code where there could be other reasons for the values to differ. Even more so if you’re not even aware of the rounding.

Knowing this might save you a couple of hours once.

Monday, December 26, 2011 7:28:18 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | .NET | SQL
# Monday, December 19, 2011

In a previous post I addressed the issue of using HTTP module based authentication in WCF. The presented solution worked in most cases but failed completely with Windows authentication. In this post I’ll describe the necessary changes to make this work as well.

Let’s first see what goes wrong with the existing solution and why. To configure WCF for Windows authentication, the following changes are required in web.config:

<system.serviceModel>
    <!-- ... -->
    <bindings>
        <basicHttpBinding>
            <binding name="HttpWindowsBinding" 
                     maxReceivedMessageSize="2147483647">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Windows" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service name="WcfAuthentication.Service">
            <endpoint address="windows"
                      binding="basicHttpBinding"
                      bindingConfiguration="HttpWindowsBinding"
                      contract="WcfAuthentication.IService" />
        </service>
    </services>
</system.serviceModel>

Of course the settings have to be matched in IIS: Windows authentication should be enabled for the application while anonymous authentication should be disabled, as well as all the other types of authentication.

After setting all this up any calls to our service will throw a MessageSecurityException: "The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'." If you try searching the web for solutions, you’ll notice the same error pops up in many different situations not related to our case. So what’s going on here?

The problem is being caused by the following method in HttpAuthenticationModule:

void context_AuthenticateRequest(object sender, EventArgs e)
{
    HttpContext.Current.User = ProcessAuthentication();
}

Setting the user in the current HttpContext to a custom IPrincipal implementation confuses WCF which expects a WindowsPrincipal as configured. The only way to make it work is to pass through the original user information in this case:

void context_AuthenticateRequest(object sender, EventArgs e)
{
    if (!(HttpContext.Current.User is WindowsPrincipal) && 
        HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.EndsWith(".svc"))
        HttpContext.Current.User = ProcessAuthentication();
}

The extension based filtering is there so that the authentication will still work for the rest of our web application. This change alone is not enough, of course. We still to need the authentication somewhere for the WCF case. HttpContextAuthorizationPolicy is the right spot for it. Evaluate method should be modified as follows:

public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
    HttpContext context = HttpContext.Current;

    if (context != null)
    {
        if (context.User is WindowsPrincipal)
        {
            IPrincipal principal = HttpAuthenticationModule.ProcessAuthentication();
            evaluationContext.Properties["Principal"] = principal;
            evaluationContext.Properties["Identities"] = new List<IIdentity> { principal.Identity };
        }
        else
        {
            evaluationContext.Properties["Principal"] = context.User;
            evaluationContext.Properties["Identities"] = new List<IIdentity> { context.User.Identity };
        }
    }

    return true;
}

Keep in mind that calling a static method in HttpAuthenticationModule to authenticate the user is just a shortcut to make this sample work and is not suggested practice. In production code you’ll want to have your authentication logic implemented somewhere in the business layer and call it from both HttpAuthenticationModule and HttpContextAuthorizationPolicy.

Monday, December 19, 2011 9:12:16 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | .NET | ASP.NET | WCF
# Monday, December 12, 2011

WCF has great built-in support for most types of authentication so there aren’t many good reasons to use HTTP module based authentication with it. Having an existing ASP.NET application already using such authentication certainly is one of them. Finding resources on how to do it might be a challenge though. I managed to stumble upon an article by Microsoft patterns & practices team which helped a lot. In a way this post is its abridged and more practical version.

From here on I assume you already have an IHttpModule in your application (ProcessAuthentication() being the method implementing the actual authentication of the user):

public class HttpAuthenticationModule : IHttpModule
{
    public void Dispose()
    { }

    public void Init(HttpApplication context)
    {
        context.AuthenticateRequest += context_AuthenticateRequest;
    }

    void context_AuthenticateRequest(object sender, EventArgs e)
    {
        HttpContext.Current.User = ProcessAuthentication();
    }

    private static IPrincipal ProcessAuthentication()
    {
        // implement your authentication here
        IIdentity identity = new GenericIdentity("Authenticated User");
        return new GenericPrincipal(identity), null);
    }
}

The module should also already be registered in web.config:

<system.web>
    <!-- ... -->
    <httpModules>
        <add name="HttpAuthenticationModule" 
             type="WcfAuthentication.HttpAuthenticationModule"/>
    </httpModules>
</system.web>

The goal is of course getting access to the authenticated user (i.e. IPrincipal instance) in WCF service through ServiceSecurityContext. The following test method is a great way for testing that:
public string GetUser()
{
    if (ServiceSecurityContext.Current != null)
        return ServiceSecurityContext.Current.PrimaryIdentity.Name;
    else
        return null;
}

IAuthorizationPolicy is the interface to implement custom authorization in WCF with. In our case the authenticated user can be accessed through current HttpContext:

public class HttpContextAuthorizationPolicy : IAuthorizationPolicy
{
    public bool Evaluate(EvaluationContext evaluationContext, ref object state)
    {
        HttpContext context = HttpContext.Current;

        if (context != null)
        {
            evaluationContext.Properties["Principal"] = context.User;
            evaluationContext.Properties["Identities"] = new List<IIdentity>() { context.User.Identity };
        }

        return true;
    }

    public System.IdentityModel.Claims.ClaimSet Issuer
    {
        get { return ClaimSet.System; }
    }

    public string Id
    {
        get { return "HttpContextAuthorizationPolicy"; }
    }
}

Of course the class should be registered in web.config so that our service will use it:

<system.serviceModel>
    <!-- ... -->
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <!-- ... -->
                <serviceAuthorization>
                    <authorizationPolicies>
                        <add policyType="
                             WcfAuthentication.HttpContextAuthorizationPolicy, 
                             WcfAuthentication, Version=1.0.0.0, 
                             Culture=neutral, PublicKeyToken=null"/>
                    </authorizationPolicies>
                </serviceAuthorization>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

There is still one thing missing. If you try out the above code, you will realize that HttpContext.Current is always null even if authorization in our HTTP module was successful. To get access to it you need to enable ASP.NET compatibility:

<system.serviceModel>
    <!-- ... -->
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" 
                               aspNetCompatibilityEnabled="true"/>
</system.serviceModel>

To make your WCF service work in this mode you need decorate it with AspNetCompatibilityRequirementsAttribute:

[AspNetCompatibilityRequirements(RequirementsMode = 
    AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
    // ...
}

Finally, we’re done. If you’ve implemented all of the above correctly, our test method GetUser() should return the user who was authenticated in the HTTP module. Unless you’re trying to use Windows authentication which still doesn’t work in this setup. That’s already a subject for another post, though.

Monday, December 12, 2011 9:29:48 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | .NET | ASP.NET | WCF
# Sunday, October 02, 2011

This year’s Bleeding Edge conference was taking place this week in the beautiful surroundings of Gozd Martuljek. The second day was dedicated to community driven redelivery of Build. As the last session of the day I had a talk on the aspects of reusing existing .NET framework code in Metro applications for Windows 8. I’ve based the contents of the talk on the following Build sessions:

The slides from my talk are available on SlideShare. Here are the sources for the sample Windows runtime component I've created during the talk.


Sunday, October 02, 2011 8:34:40 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | Metro | Downloads | Presentations | Sources
# Sunday, July 24, 2011

Reflection is a great tool for calling methods on objects when their types are not known at compile time. Unfortunately the Type.GetMethod method doesn’t work with generic methods therefore we seem to be stuck with finding the right method by iterating through all the methods returned by Type.GetMethods:

public static MethodInfo GetMethodWithLinq(this Type staticType, string methodName, params Type[] paramTypes)
{
    var methods = from method in staticType.GetMethods()
                  where method.Name == methodName
                        && method.GetParameters()
                                  .Select(parameter => parameter.ParameterType)
                                  .Select(type => type.IsGenericType ? type.GetGenericTypeDefinition() : type)
                                  .SequenceEqual(paramTypes)
                  select method;
    try
    {
        return methods.SingleOrDefault();
    }
    catch (InvalidOperationException)
    {
        throw new AmbiguousMatchException();
    }
}

Searching for alternatives I stumbled upon a solution using expression trees posted by Neil Whitaker on StackOverflow:

private static MethodInfo GetMethodWithExpressions(Type innerType)
{
    var method = typeof(Program).GetMethod("GetSingleOrDefaultMethod", 
                                           BindingFlags.Static | BindingFlags.NonPublic, 
                                           null, Type.EmptyTypes, null)
                                .MakeGenericMethod(innerType);
    return method.Invoke(null, new object[] { }) as MethodInfo;
}

private static MethodInfo GetSingleOrDefaultMethod<TSource>()
{
    Expression<Func<TSource, bool>> fakePredicate = i => true;
    Expression<Func<IQueryable<TSource>, TSource>> lambda = l => l.SingleOrDefault(fakePredicate);

    return (lambda.Body as MethodCallExpression).Method;
}

Sure, it is more difficult to comprehend and a lot less flexible, requiring a helper method building the expression tree for every method to be returned as MethodInfo. It got me wondering though, which of the two solutions actually performs better. Let’s try them out:

static void Main(string[] args)
{
    MethodInfo method;
    Type innerType = typeof(string);

    int count = 10000;
    Stopwatch stopwatch = new Stopwatch();

    stopwatch.Restart();
    for (int i = 0; i < count; i++)
    {
        method = typeof(Queryable).GetMethodWithLinq("SingleOrDefault", typeof(IQueryable<>), typeof(Expression<>))
                                  .MakeGenericMethod(innerType);
    }
    stopwatch.Stop();
    Console.WriteLine(String.Format("Method 1: {0}", stopwatch.ElapsedMilliseconds));

    stopwatch.Restart();
    for (int i = 0; i < count; i++)
    {
        method = GetMethodWithExpressions(innerType);
    }
    stopwatch.Stop();
    Console.WriteLine(String.Format("Method 2: {0}", stopwatch.ElapsedMilliseconds));

    Console.ReadLine();
}

And the results?

Method 1: 224
Method 2: 396

Not only is the Type.GetMethods based approach simpler, it also consistently performs a lot better. We’ll just stick with it until support for generic methods is added to Type.GetMethod.

Sunday, July 24, 2011 10:31:43 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | C#
# Sunday, June 12, 2011

XmlSerializer is often a great choice for persisting objects or transmitting them over the wire, either by using default object serialization tailored only with attributes or by implementing the IXmlSerializable interface yourself. If you’re not careful though, this might come at a significant performance cost.

You’re probably already aware that in order to increase performance of XML serialization, assemblies are dynamically generated each time XmlSerializer is instantiated for the first time for a specific type. Since it happens only once in the application lifetime, it usually doesn’t pose much of a problem.

What you might not know, is that this is not necessary a once in a lifetime process. If you’re using the wrong constructor, it can happen every time you instantiate XmlSerializer. To be fair, this is mentioned in the documentation, but if you’re like me, you might not read it until you encounter performance issues in your project. So unless you’re calling XmlSerializer(Type) or XmlSerializer(Type, String), the dynamically generated assemblies are not reused. When you think about it, it also makes perfect sense. All other constructors modify the behavior of the serializer, thus causing small differences in the generated serializers and hindering their reuse.

Fortunately there is a way to avoid this performance hit. Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application. The only thing left for you to do, is to devise a way to always retrieve the same instance. If you know in advance which serializers you’ll need, you can simply store them in static fields. If you don’t, you’ll need to store them in a dictionary, keyed by the arguments used in the constructor.

Your best choice for the data structure is ConcurrentDictionary introduced in .NET 4 which takes care of synchronizing for multithreading. This makes the implementation really simple:

private static ConcurrentDictionary<Type, XmlSerializer> serializers = 
    new ConcurrentDictionary<Type, XmlSerializer>();

private XmlSerializer GetSerializer(Type type)
{
    return serializers.GetOrAdd(type, t => 
        { return new XmlSerializer(t, new XmlRootAttribute("Value")); });
}

If you’re wondering what kind of performance hit I’m talking about, try running the following sample:

static void Main(string[] args)
{
    StringWriter writer = new StringWriter();
    XmlTextWriter xmlWriter = new XmlTextWriter(writer);
    xmlWriter.WriteStartDocument();
    xmlWriter.WriteStartElement("Root");
    Stopwatch stopwatch = new Stopwatch();
    int iterations = 100;

    stopwatch.Restart();
    for (int i = 0; i < iterations; i++)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(string));
        serializer.Serialize(xmlWriter, "Test");
    }
    stopwatch.Stop();
    Console.WriteLine(
        "{0} serializations with XmlSerializer(string):                   {1,5} ms",
        iterations, stopwatch.ElapsedMilliseconds);

    stopwatch.Restart();
    for (int i = 0; i < iterations; i++)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(string), new XmlRootAttribute("Type"));
        serializer.Serialize(xmlWriter, "Test");
    }
    stopwatch.Stop();
    Console.WriteLine(
        "{0} serializations with XmlSerializer(string, XmlRootAttribute): {1,5} ms",
        iterations, stopwatch.ElapsedMilliseconds);

    XmlSerializer staticSerializer = new XmlSerializer(typeof(string), new XmlRootAttribute("Type"));
    stopwatch.Restart();
    for (int i = 0; i < iterations; i++)
    {
        staticSerializer.Serialize(xmlWriter, "Test");
    }
    stopwatch.Stop();
    Console.WriteLine(
        "{0} serializations with a static serializer:                     {1,5} ms",
        iterations, stopwatch.ElapsedMilliseconds);

    Console.ReadKey();
}

In my case the output was as follows:

100 serializations with XmlSerializer(string):                       2 ms
100 serializations with XmlSerializer(string, XmlRootAttribute): 17460 ms
100 serializations with a static serializer:                         2 ms

Quite a difference, isn’t it?

Sunday, June 12, 2011 4:55:48 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET
# Wednesday, June 08, 2011

One of the features introduced in Entity Framework 4 was support for foreign key properties in entity types. No matter what your opinion is about having foreign keys exposed by an ORM, there are some cases where it might be more practical or even more performant to use foreign key properties instead of navigation properties (e.g. when you are creating a new object with a reference for which you know the primary key value but don’t have a corresponding object in your ObjectContext). That’s the reason why it’s usually recommended to include foreign key columns in your model even though it will pollute your entity types with properties you might not need at all.

Update Wizard

But what if you decided not to include them in your model when you originally created it, but want to add them at a later time? Although the checkbox is enabled in the model Update Wizard which opens up when you want to Update Model from Database, its value only effects newly created entity types, but leaves existing entity types unchanged. Unless you feel comfortable deleting existing entity types and recreating them from database, you’ll have to add the properties by hand. Once you know how to do it, it’s just a matter of following a few simple steps. I’ll describe them on a simple example from Northwind database. I’ve only included three entity types: Category, Product and Supplier. We want to add CategoryID and SupplierID properties to the Product entity type.

Model without Foreign Key Properties

First add a new scalar property to the entity type:

  1. Right click on the Product entity type.
  2. Click on the Add > Scalar Property from the context menu.
  3. Click on the newly created Property and set its properties: Name to CategoryID, Nullable to True and Type to Int32.

CategoryID Properties Window

Next you need to map the database column to your new property:

  1. Open Mapping Details for Product entity type.
  2. Select the CategoryID : Int32 as Value / Property for the CategoryID : int column.

Product Mapping Details Window

Now it’s time to set up the referential constraint:

  1. Select the FK_Products_Categories association in the Model Browser.
  2. Open the Referential Constraint editor from its properties window.
  3. Select Category as Principal and CategoryID as Dependent Property.

Referential Constraint Editor

Only one step left, deleting the mapping of foreign key to the navigation property which is not allowed when you have a foreign key property in your entity type:

  1. Select the Category property of the Product entity type.
  2. Click on the Delete mappings link displayed in the Mapping Details window.

Category Mapping Details

You have to repeat the above steps for the SupplierID property and you have created a functionally identical model to the one automatically generated for you if you had selected to include foreign keys in the model before adding the tables to it.

Model with Foreign Key Properties

The above process is not only useful when you change your mind about the foreign key properties at a later time. You can also intentionally decide to add the foreign key properties only when you actually need them and avoid having redundant properties at the cost of the consistency of the model.

Wednesday, June 08, 2011 9:43:08 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | EF4
# Saturday, May 28, 2011

This week the annual Microsoft conference NT konferenca 2011 was taking place in Portorož. On Tuesday I had a talk there about the Windows API Code Pack. As promised, you can find the slides from this talk on SlideShare.

You can also download the sources for the sample project which is a working WPF MVVM image viewer application demonstrating the implementation of:

Saturday, May 28, 2011 12:03:33 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | Interop | WPF | Downloads | Presentations | Sources
# Wednesday, March 23, 2011

It seems that no matter how much experience one has with .NET framework, there are still surprises awaiting him somewhere down the road. This time I’d like to point out an interesting behaviour of MethodInfo.Invoke many of you might not be aware of. I certainly wasn’t, until today.

Since this is well documented, I should start with a quote from the documentation for the parameters parameter: “An argument list for the invoked method or constructor. […] Any object in this array that is not explicitly initialized with a value will contain the default value for that object type. For reference-type elements, this value is null. For value-type elements, this value is 0, 0.0, or false, depending on the specific element type.”

What exactly does this mean? If you pass a null as a value for a value-type parameter, the call won’t fail as you might have expected. Instead, the default value for that type will be set as the parameter value.

The following short sample demonstrates this behaviour:

public void WriteValue(int value)
{
    Console.WriteLine("value = {0}", value);
}

public static void Main(string[] args)
{
    // this will result in a compile error:
    // Argument 1: cannot convert from '<null>' to 'int'
    WriteValue(null);

    // this will output:
    // value = 0
    Type type = typeof(Program);
    MethodInfo method = type.GetMethod("WriteValue");
    method.Invoke(new Program(), new object[] { null });

    // this will throw a RuntimeBindingException:
    // The best overloaded method match for 'Program.WriteValue(int)' has some invalid arguments
    dynamic obj = new Program();
    obj.WriteValue(null);
}

Obviously calling the method directly with a null value won’t even compile (unless you change the parameter type to Nullable<int>). The Reflection based call succeeds by passing the default value (0 for int) as the parameter value. The dynamic type doesn’t exhibit this behaviour – the call fails with a runtime exception.

Wednesday, March 23, 2011 9:21:12 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | .NET
Page 1 of 4 in the DevelopmentNET category Next Page
Sponsored Ads

About Me
Twitter
@MladenPrajdic @andrejt use the middle mouse button then 2 days ago
Great #DotNetRocks show: Troy Hunt Secures http://t.co/oxClbXLe http://t.co/MiMasNuZ PDF is worth checking out as well http://t.co/z4BHAzqh 3 days ago
Hazards of Converting Binary Data To A String http://t.co/lb8kRSsU via @haacked 5 days ago
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2012, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)
Social Network Icon Pack by Komodo Media, Rogie King is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.