5/30/11

LINQ to SQL with NOLOCK

If your project uses LINQ to SQL for your database access, you may want to use NOLOCK to set the isolation level to ReadUncommitted on your select statements. The problem is that LINQ does not understand query hints. The way this works with LINQ is by running your select statements under the context of a transaction scope as follows:
string type = string.Empty;
og-bit.com

using (DataContext ctx = new DataContext(ConnectionString))
{
  using (var tx = new System.Transactions.TransactionScope(TransactionScopeOption.Required,
         new TransactionOptions() { IsolationLevel = IsolationLevel.ReadUncommitted }))
  {
         var row = (from record in ctx.Log
                    where record.Id == 99999
                    select record).FirstOrDefault();
         type = row.Type;
  }
}

The code here creates a transaction scope and sets the isolation level to ReadUncommitted (NOLOCK). The select statement runs under the scope of the transaction, and it returns the value from a query. The using clause ensures that both the transactions as well as the data context are disposed once the code goes out of scope.

There is also the preferable option to use stored procedures to eliminate the need to use transaction scope. In the store procedure, you have the flexibility to use query hints.

I hope this helps.

og-bit.com

5/25/11

The HTTP request is unauthorized with client authentication scheme 'Basic'

There are several examples on the internet that focus on implementing a custom username password validator for a WCF service. Most of those samples are written using self-hosted applications and work as designed. There is a problem however when the same approach needs to be implemented using an IIS hosted site with Basic authentication enabled. If you have implemented a custom user name password validator for non-windows credentials and with the following settings:

<basicHttpBinding>
  <binding name="basicHttp" closeTimeout="00:01:00" openTimeout="00:01:00"/>
       <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Basic" proxyCredentialType="None" realm="" />
        </security>
  </binding>
</basicHttpBinding>

You probably came across this error:
The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Negotiate,NTLM,Basic realm="localhost"'
This error indicates that the user credentials provided on the request are not valid for this realm (localhost). IIS is expecting to get a user that it can find on the local machine or domain. If you provide an existent local or active directory credential, the error will no longer be raised. However, you probably did not want to add Windows accounts for your custom authentication in the first place. In addition, even if you are using a local account, you can notice that the custom validator Validate method is never called. This is expected because IIS has already done the validation.
To get this to work on IIS, you can try the following settings:
<basicHttpBinding>
  <binding name="basicHttp" closeTimeout="00:01:00" openTimeout="00:01:00"/>
       <security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" algorithmSuite="Default" />
        </security>
  </binding>
</basicHttpBinding>

We are changing the security mode to use transport with message credential which expects a message credential type. We set the credential type to UserName. This setting however requires for you to install a certificate on your local IIS and use HTTPS instead of HTTP, so make sure to change the endpoint address in both client and server config files to use HTTPS.  For your development environment a Self-Signed certificate will be sufficient.
I hope this small article is able to help.

og-bit.com

5/19/11

WCF Service operations can’t be loaded due to mixing of message contract types and primitive types

When debugging your WCF Service, you may encounter the following error:
The operation could not be loaded because it has a parameter or return type of type System.ServiceModel.Channels.Message or a type that has MessageContractAttribute and other parameters of different types. When using System.ServiceModel.Channels.Message or types with MessageContractAttribute, the method must not use any other types of parameters
This basically means that a particular operation is using a combination of message contract types and primitive types in any of the following combinations:
  • MixType1: Contract type and primitive types as operation parameters
  • MixType2: Contract type as a parameter and primitive type as return type
  • MixType3: Primitive type as a parameter and Contract type as return type
Any of the scenarios listed above would generate the error. Let’s take a look at a ServiceContract that can generate this problem.
[ServiceContract]
public interface IRegisterMixed
{
        [OperationContract]
        Confirmation Register(string firstName, string lastName);

        [OperationContract]
        string RegisterComplex(Person person);
}

These are the message contract types:

[MessageContract]
public class Person
{
        public string FirstName { set; get; }
        public string LastName { set; get; }       
}

[MessageContract]
public class Confirmation
{
        public string AccountId { set; get; }       
}

The service contract generates the error because both operations are mixing contract types with primitive types. The Register operation has the operation parameters as primitive types and the return type as a contract type (MixType3). The RegisterComplex operation has a contract type as parameter and a primitive type as return type (MixType2).

A way to address this would be to modify the service contract as follows:

[ServiceContract]
public interface IRegisterOK
    {
        [OperationContract]
        string Register(string firstname, string lastname);
      
        [OperationContract]
        Confirmation RegisterComplex(Person person);
}

As you can see, both operations are consistently using either primitive types or contract types for both operation and return parameters.

I hope this tip would be useful when designing your next WCF Service operations.

og-bit.com

5/14/11

WCF Service Project Properties is missing the WCF Options Tab

If your WCF Library project does not auto start the WCF Service host when trying to start the project in debug mode, the project file has some missing elements. A way to check this is to right click on the project name (Visual Studio) and look for the WCF Options tabs on the left side of the window.  If you do not see the tab, this means that the library project for some reason was not created as a WCF library.   
A quick way to resolve this is to create a new WCF Service Library project and copy all the files over. If you do not want to do this, you can manually modify the project file and add the missing elements as follows:
·         Right click the project name and select Open Folder in Windows explorer
·         Look for your project file which should end with a .csproj extension and open the file with your favorite editor or just notepad.
·         In the first PropertyGroup element do the following:
o   Look for the ProductVersion element. Update the product version to match the following: 
<ProductVersion>8.0.50727</ProductVersion>

o   Below the AssemblyName element, add the following elements:
<ProjectTypeGuids>{3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<StartArguments>/client:"WcfTestClient.exe"</StartArguments>

o   Scroll to the end of the file, and below the Import  element add the following extension:
<ProjectExtensions>
    <VisualStudio>
      <FlavorProperties GUID="{3D9AD99F-2412-4246-B90B-4EAA41C64699}">
        <WcfProjectProperties>
          <AutoStart>True</AutoStart>
        </WcfProjectProperties>
      </FlavorProperties>
    </VisualStudio>
  </ProjectExtensions>

o   Save the file and select yes when Visual Studio prompts to reload the project.
The changes update the project type from a basic library project to a WCF Service library. You can now do project properties and should see the WCF Options tab. The Start WCF service host option should be checked. You can now run the project in debug mode, and the WCF Service Host should start.
I hope this save you some time and thanks for reading.

og-bit.com