Wednesday, June 27, 2012

To var or not to var?

I have recently started using Resharper in Visual Studio 2010.  I enjoy using the tool and mostly agree with the suggestions it makes and rules it has for syntax and styling.  However, I find the rules around the var keyword to be going against my sense of code style.  Take the following code snippet:

int x = 12;

Resharper would have me use the var keyword here, per the rule "use 'var' keyword whenever possible".  So according to the resharper rule, this line should be written as:

var x = 12;

To me, this is less readable than the previous version.  Did I mean for x to be an int?  Maybe I needed an int16, or possibly a uint64?  Possibly I was mistaken altogether and needed a float.  For me, I would like the opposite rule, "use 'var' keyword only when required".

This is a big debate in the C# world.  More dicussion can be found at:

http://www.infoq.com/news/2008/05/CSharp-var

Personally, I come down on the side of minimal var usage.  When I want to use var everywhere and implicit type inference, I will go write some JavaScript.

Friday, June 22, 2012

Dynamic Response Formats with WCF REST 4

I recently had a need to return data from a RESTful service in more than one format.  The consumers of the service had varying needs, some preferred XML, others wanted JSON.  WCF REST 4 provides both types of output serialization very simply by decorating your exposed method with the ResponseFormat attribute:

[WebGet(UriTemplate = "/SomeData/?dataId={categoryId}", ResponseFormat = WebMessageFormat.Json)]

However, what do you do if you want to set the output type based on the consumer's preference?  The key is to modify the OutgoingResponse.Format property of the WebOperationContext object per the caller's preferences.

[WebGet(UriTemplate = "/SomeData/?dataId={categoryId}&format={format}"
public class DataObjects SomeData(int dataId, string format)
{
if (format == "json")
   WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Json;
...

Now your consumer can specify which output formatter is appropriate for their situation.  This wreaks havoc with the auto generated WSDL and may not be appropriate for public APIs but works well on services with known target audiences.

Monday, June 11, 2012

Debugging WCF REST Services

Recently I was working with a WCF Rest Service based on the WCF Rest 4 template. Not far removed from the original project template, I was working towards returning data from an underlying database using entity framework models and ran into some issues. There are known issues with attempting to do what I was doing, but that is for another post. In this case, I had an action returning results in Json. The method was using the inbuilt JSON serializer decorated as:

        [WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]
        public List<SampleItem> GetCollection()
        {
            return new List<SampleItem>() { new SampleItem() { Id = 1, StringValue = "Hello" } };
        }

This method is very simple and is the out of the box implementation of a default GET action in the Rest 4 Template. The decorator ResponseFormat = WebMessageFormat.Json instructs the framework to utilize the DataContractJsonSerializer class to format your function's results into Json format, ready for consumption by some caller.

Under the covers the WCF Runtime is calling your method, obtaining the results, and then formatting the results into Json and return it to the client. If you want to go deep into the details of this implementation, Carlos Figuiera has a post on his blog detailing implementation of your own formatter: http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/wcf-extensibility-message-formatters.aspx

Now lets throw something at it that the JsonDataContractSerializer can't handle:

    [EdmEntityTypeAttribute(NamespaceName="DatabaseModel", Name="CUSTOMER")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class CUSTOMER : EntityObject
    {

If we change our webmethod to return type CUSTOMER like this:

        [WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]
        public List<CUSTOMER> GetCollection()
        {
            return new List<CUSTOMER>() { new CUSTOMER() { Id = 1, FirstName = "Hello" } };
        }

The DataContractAttribue(IsReference=true) decoration on the CUSTOMER class causes an error in the JsonDataContract serializer.  However, our implementation of the web service is not exposed to the error within the context of the method call being evaluated.  This is shown when we execute the method from Fiddler:


Instead of an exception encoded in the HTML on the page, the web server returns a 504 error, no response returned for this request.  How do we see what happened, why did the call fail, how do we troubleshoot this?

We need to use WCF tracing in order to see the errors occuring here.  We must enable diagnostic tracing by adding a configuration block to our Web.config:

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="All"
              propagateActivity="true" >
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "c:\log\Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

With this tracing enabled, a file is written containing a tracelog of all activity that is traceable.  The level of tracing is set with the switchValue setting.  You will need to ensure that your executing process has write permissions to the file location specified.  The tracelog can be opened with the Microsoft Service Trace Viewer and we can step through each trace item and look at the details.  This reveals the real error:


The trace log gives us the error message within WCF and we can now troubleshoot the issue from there.  For more details on WCF Tracing see MSDN at: http://msdn.microsoft.com/en-us/library/ms733025.aspx

Friday, June 8, 2012

Process explorer

The Sysinternals team at Microsoft just released a new version of the process explorer with some great new features. I’m sure you have used it before, but this is a great debugging and analysis tool, if you haven’t used it before, the SysInternals group of tools allow you to graphically get under the hood of windows in some very powerful ways. Process explorer in particular allows you to see executing processes, what files they have open, what resources they are using, memory usage, threads, etc… extremely powerful! Do you know what your .Net app really does? Check it out at: Process Explorer

Monday, June 4, 2012

MVC.Net 3 and Team Foundation Build

A lot has been written about bin deployments of MVC.Net 3 and seperately about building MVC.Net 3 projects on Team Foundation Build.  I haven't seen anyone put the whole package together in a step by step format, so this post is inteded to do just that.  The issue here is that TFS Build by default does not copy required MVC.Net 3 dependencies to the output folder.  When you install your MVC.Net 3 application from the build server's output on a server that doesn't have MVC.Net 3 installed from the Microsoft MSI your app won't run because the required dependencies aren't there.  This article shows you step by step how to fix that.  You'll need Visual Studio 2010 SP1 for this to work.

  1. From your project, right click on your project and select 'Add Deployable Dependencies'
  2. Choose 'ASP.Net Web Pages with Razor Syntax' (You are using razor right?) and click OK.
  3. Visual Studio will add a folder called _bin_deployableAssemblies and put the proper .dlls in there for you
  4. Now, edit your .csproj file and add the following XML inside of the <Project></Project> tag: 
  <Target Name="CopyBinDeployableAssemblies" AfterTargets="CopyFilesToOutputDirectory" Condition="Exists('$(MSBuildProjectDirectory)\_bin_deployableAssemblies')">
     <ItemGroup>
         <_binDeployableAssemblies Include="$(MSBuildProjectDirectory)\_bin_deployableAssemblies\**\*.*" />
         <FilesForPackagingFromProject Include="%(_binDeployableAssemblies.Identity)">
                         <DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
         </FilesForPackagingFromProject>
     </ItemGroup>

     <Copy SourceFiles="@(_binDeployableAssemblies)" DestinationFolder="$(OutDir)%(RecursiveDir)" SkipUnchangedFiles="true" />
     <Copy Condition="'$(WebProjectOutputDir)' != ''" SourceFiles="@(_binDeployableAssemblies)"             DestinationFolder="$(WebProjectOutputDir)\bin\%(RecursiveDir)" SkipUnchangedFiles="true"/>
  </Target>

This XML will instruct the build server to copy the contents  of the folder created by Visual Studio to the output folder.  Check in your changes and check your drop folder for success.