Friday, December 9, 2011

WCF Web API security in a domain

I've been building REST services using WCF Web API for use in an intranet. Upon deployment from my desktop to a server I started experiencing the error below even though the hosting application, ASP.NET MVC 3, was successfully using Windows authentication.

System.NotSupportedException: Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.

A Google search shows that this isn't a novel situation, but I couldn't get the configuration and incantation right for Web API. Luckily, after a couple of hours of researching and fiddling with the web.config, I came across this post that revealed the solution to me.

When registering the service route:
var config = new HttpConfiguration();
   config.Security = (u, s) => {
      s.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
      s.Mode = HttpBindingSecurityMode.TransportCredentialOnly;
   };

   routes.MapServiceRoute<YourType>("YourRoutePrefix", config);

I hope that this post saves someone some time.

Tuesday, December 6, 2011

MvcBuildViews in a CI environment

This post isn't going to break any new ground in the world of computer science, but I still wanted to say a few words about the importance of using MvcBuildViews in your continuous integration environment.

My team had just finished a quick and slightly dirty ASP.NET MVC 3 project. The three of us rapidly created a very usable internal departmental financial application with two of the members of the team being ASP.NET MVC neophytes. A lot of learning occurred during development, both about the basics of HTTP and client scripting as well as Visual Studio's ASP.NET MVC 3 tooling.

I was finishing off numerous TODO's toward the end of the project when I entered "/p:MvcBuildViews=true" in the MSBuild arguments section of the Team Build process tab. The build crashed immediately due to nonexistent namespace issues. It seems that a family of CRUD Views had been created at some point that used a Model that no longer existed. Apparently the plan had been to go back and clean up dead code, but there was never any follow-up due to other priorities. The dead Views certainly weren't hurting anything. Also, a user could only access them if they somehow typed in the correct URL, a near impossible eventuality. However, I abhor dead code and extra files in a project. It not only distorts the size and complexity of a project but also increases the size of the deployment.

Using MvcBuildViews helped me remove four Views from our final deployment package. That's a trivial amount for large, enterprise projects. However, for a small department application likes ours, that's 20% of the Views. So not only are there now dramatically fewer Views to manage, the steepness of the learning curve for new developers is reduced.

Thursday, December 1, 2011

Anyone looking for work in Kathmandu?

I certainly have never been contacted about such an exotic job opportunity!


On November 16, 2011 at 1:00 AM Fine Tuners  wrote:

Dear Sir/Madam,
 
We have explored your company as one of the best ever growing software development company.  This is what we are interested in. 
FineTuners is a Kathmandu based software development and web development company. Our Outsourcing firm is  located at the heart of Nepal, Kathmandu. Nepal is well known for its culture, natural resources and on the top for Mount Everest, the highest pick of the world.
At present we are mainly focusing on the following areas as per the need of ever growing market:
·        Web services( Slicing/ Development/ full shop)
·        Web applications from simple web portals to the dynamic ecommerce sites)
We are a highly experienced team of intellectuals who are versatile in different development tools. Actually we are providing with different kinds of services, based on your requirement which you can choose. Else you can let us know the brief requirements of your projects such as technology, and services you require.
If this is the interest of yours, we are always standby to assist. You can explore us more via: www.fintuners.com . We are here to provide you with unlimited opportunities.
 
We offer you a trail project. If you like the work, then you pay us else you don’t have to pay for what is done. This is the best deal we can offer you to build up the trust.
     
     
    -- 
     
    -- 
    Best Regards,
    Sachit Pokhrel
    FineTuners
    www.fintuners.com
    skype: sunilpokharel1

Monday, August 22, 2011

SSRS 2208 Multi-value Default Parameters Not Being Used

I spent about an hour trying to track down what was causing my default multi-values from appearing in Business Intelligence Development Studio (BIDS) AKA Visual Studio 2008 (VS2008).

My dataset is simply a one-dimensional list of names of human beings, such as John Doe. The default values are were a subset of those names but they were not being selected either in Preview in BIDS or on the server.

This post gave me the idea to check my list of default values against the dataset. I knew that I didn't have NULL values in my dataset, but I realized that I did have some default values that didn't correspond to the list of values in my dataset. The default values had until recently matched their counterparts in the dataset, but staff turnover had changed two of the values from "Firstname Lastname" to "Firstname Lastname (DOMAIN\USERNAME)". As soon as I removed the two non-corresponding values all was well- the default values were selected as desired and the report again started executing as expected.

Tuesday, August 9, 2011

ELMAH, NuGet, SQL Server Compact 4.0, and EF Code-First

ELMAH + NuGet + SQL Server Compact 4.0 + EF Code-First = Trouble!

Following Scott Hanselman's directions, I installed ELMAH on Microsoft SQL Server Compact 4.0 (SQL CE). Because of the dependency of 'ELMAH on MS SQL Server Compact' on SQL CE (and I already had the 'Manage NuGet Packages' window open) I let NuGet install it for me. NuGet installed everything perfectly and soon I was happily logging exceptions and storing them in a *.sdf file. Cool.

I also used NuGet to install Entity Framework 4.1 and followed Scott Guthrie's post on Code-First Development with Entity Framework 4. I created a model, added a connection string to my ASP.MVC 3 application, and soon I was persisting data to a second *.sdf file. Still cool.

Finally it was time to push my application to a server. This is where things became uncool.

Could not load file or assembly 'System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.
After confirming that System.Data.SqlServerCe.Entity was in the bin directory, I started reviewing the versions of the SQL CE files, and then just to be sure I copied all of the files from my local installation of SQL CE to the server again. The problem still persisted.

I had used NuGet to install the version of SQL CE that ELMAH was using so I decided to research what the expected file versions were. These two great posts by ErikEJ caused me to formulate a theory that perhaps ELMAH and EF 4.1 were using the wrong or conflicting file versions. I made two changes to my application to test my theory.
  1. Altered DbProviderFactories in my web.config file as described in this article.
  2. Set up a binding redirect for System.Data.SqlServerCe as described in this article.
After making these two changes exception logging and data persistance to my two compact databases started working on the server. Maybe it's just me but it seems that a significant percentage of development troubleshooting is pure intuition!

Wednesday, June 1, 2011

Installing Rails From Behind A Corporate Proxy

I had a little extra time on my hands and wanted to experiment with Ruby on Rails. The articles that I had read raved about how easy it was to set up the development environment using RubyGems.

Latest versions of Ruby and RubyGems were downloaded and installed without incident. Where I ran into a big problem was installing Rails and its dependencies. Initially I tried to run "gem install rails" but the operation failed due to proxy authentication issues, and this is a well known limitation.

I thought that I would manually download and install the gems but this would have taken hours. As usual, a StackOverflow post provided the inspiration to use CNTLM.

Initially I couldn't get CNTLM to authenticate properly because I didn't know the correct authentication type. The CNTLM manual indicated that there is a switch ("-M") that will test various authentication types using "magic NTLM dialect detection" (!). Using "cntlm -M http://www.google.com" revealed the correct mode that I should use. After making the change in cntlm.ini and restarting the CNTLM service I was able to successfully install rails using the following command:

gem install rails --http-proxy http://localhost:3128

Here's a sampling of the errors that I experienced as well as a successful download:

C:\Ruby192\bin>gem install rails --http-proxy http://localhost:3128
C:\Ruby192\bin>gem install rails
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    too many connection resets (http://rubygems.org/gems/abstract-1.0.0.gem)

C:\Ruby192\bin>gem install rails --http-proxy http://localhost:3128
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    bad response Not Found 404 (http://rubygems.org/gems/abstract-1.0.0.gem)

C:\Ruby192\bin>gem install rails --http-proxy http://localhost:3128
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    bad response Proxy Authorization Required 407 (http://rubygems.org/gems/abstract-1.0.0.gem)

C:\Ruby192\bin>gem install rails --http-proxy http://localhost:3128
Fetching: abstract-1.0.0.gem (100%)
WARNING: abstract-1.0.0 has an invalid nil value for @cert_chain
Fetching: erubis-2.6.6.gem (100%)
Fetching: actionpack-3.0.7.gem (100%)
Fetching: arel-2.0.10.gem (100%)
Fetching: activerecord-3.0.7.gem (100%)
Fetching: activeresource-3.0.7.gem (100%)
Fetching: mime-types-1.16.gem (100%)
Fetching: polyglot-0.3.1.gem (100%)
Fetching: treetop-1.4.9.gem (100%)
Fetching: mail-2.2.19.gem (100%)
Fetching: actionmailer-3.0.7.gem (100%)
Fetching: thor-0.14.6.gem (100%)
Fetching: railties-3.0.7.gem (100%)
Fetching: rails-3.0.7.gem (100%)
Successfully installed abstract-1.0.0
Successfully installed erubis-2.6.6
Successfully installed actionpack-3.0.7
Successfully installed arel-2.0.10
Successfully installed activerecord-3.0.7
Successfully installed activeresource-3.0.7
Successfully installed mime-types-1.16
Successfully installed polyglot-0.3.1
Successfully installed treetop-1.4.9
Successfully installed mail-2.2.19
Successfully installed actionmailer-3.0.7
Successfully installed thor-0.14.6
Successfully installed railties-3.0.7
Successfully installed rails-3.0.7
14 gems installed
Installing ri documentation for abstract-1.0.0...
Installing ri documentation for erubis-2.6.6...
Installing ri documentation for actionpack-3.0.7...
Installing ri documentation for arel-2.0.10...
Installing ri documentation for activerecord-3.0.7...
Installing ri documentation for activeresource-3.0.7...
Installing ri documentation for mime-types-1.16...
Installing ri documentation for polyglot-0.3.1...
Installing ri documentation for treetop-1.4.9...
Installing ri documentation for mail-2.2.19...
Installing ri documentation for actionmailer-3.0.7...
Installing ri documentation for thor-0.14.6...
Installing ri documentation for railties-3.0.7...
Installing ri documentation for rails-3.0.7...
Installing RDoc documentation for abstract-1.0.0...
Installing RDoc documentation for erubis-2.6.6...
Installing RDoc documentation for actionpack-3.0.7...
Installing RDoc documentation for arel-2.0.10...
Installing RDoc documentation for activerecord-3.0.7...
Installing RDoc documentation for activeresource-3.0.7...
Installing RDoc documentation for mime-types-1.16...
Installing RDoc documentation for polyglot-0.3.1...
Installing RDoc documentation for treetop-1.4.9...
Installing RDoc documentation for mail-2.2.19...
Installing RDoc documentation for actionmailer-3.0.7...
Installing RDoc documentation for thor-0.14.6...
Installing RDoc documentation for railties-3.0.7...
Installing RDoc documentation for rails-3.0.7...

Friday, February 18, 2011

A FileNotFoundException, Wrapped In A CommunicationException

For some time I've been involved in an effort to run an existing intranet Windows Forms application in an extranet configuration. It's been quite a struggle because the original app, which I'll refer to as CRAM, was never designed to NOT run in our corporate intranet. The process has required altering firewall rules, server and database configuration, new deployment scripts, and many more things than I care to remember.

A couple of days ago I thought everything was finally finished. One last error to resolve:
System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:04:59.8798782'.
Surely this was just another WCF configuration issue, right? I fired up Wireshark to diagnose the problem. Hmmm, Wireshark showed that a call to a SQL Server 2008 R2 Reporting Services (SSRS) web service was being rejected as 401 Unauthorized. Thinking that authentication was failing, I embarked on a journey of discovery where I learned about SSRS web service changes between the 2005 and 2008 versions. At one point I changed the account under which the SQL Server services run, thinking that the current accounts didn't have the required network access to properly authenticate web service callers. But after this frenzy of learning and tweaking / hacking CRAM still was throwing the same exception.

Lucky for me the original developer had the foresight to log the WCF calls. Using Service Trace Viewer I was able to get a lot more detail about the communication error but not the root cause. Buried in all of this information was another error that I hadn't seen on the client or Event Log:
System.IO.FileNotFoundException: Could not load file or assembly 'Oracle.DataAccess, Version=2.111.6.20, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. The system cannot find the file specified.
Must be a deployment issue, I thought. It didn't seem to be directly related to the communication issue, and it was appearing after the communication errors. I decided to fix the FileNotFoundException to reduce the amount of event tracing data for me to process as well as reassure myself that I wasn't a total failure.

The problem with the Oracle.DataAccess reference is that the required version wasn't present on the application server. I changed the reference's Specific Version property to False, compiled, deployed, and still got the same error. I looked at the installed Oracle client versions on the intranet and extranet application servers and noticed that they were different. I then copied the Oracle.DataAccess.dll (version 2.111.6.20) to CRAM's extranet application server so that it would function as a private assembly. Same result upon running CRAM: FileNotFoundException. Recalling a previous project where I needed to deploy Oracle.DataAccess as a private assembly I copied the same set of dll's to CRAM's executable directory.

And that was the answer. CRAM required a version of Oracle.DataAccess that was unavailable on the application server. Apparently this caused an exception that set off a chain of events resulting in the System.ServiceModel.CommunicationException that vexed me for so long. What I've learned from this- and I probably should have already known this- is that when troubleshooting WCF errors you can't only look at the error on the client: the server must also be taken into account as well. The sheer disconnected nature of WCF means that one might not be getting the complete set of information if only one side of the client + server equation is examined.

Further reading:
Copying Oracle.DataAccess as a private assembly
SSRS configuration changes