Wednesday, April 24, 2013

Calling a WCF-WSHttp service from SOAPUI


SOAPUI is a great free tool that helps you to frame up request messages generated based on a service’s metadata and use them to call on HTTP based SOAP services as well amongst other advanced features.
One of the most common questions I have been approached for recently is how to use SOAPUI to call on a WCF service with a WCF-WSHttp binding.  If you create a SOAPUI project based on your service’s WSDL and try running one of the requests without changing any of the advanced options then you will get an error message like the following – “The message with To ” cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher.  Check that the sender and receiver’s EndpointAddresses agree.”  You would not face this problem with a default WCF-BasicHttp binding.
The reason for this is that the WCF-WSHttp binding makes use of WS-Addressing which is an advanced feature that allows for messages to be easily routed through firewalls and other intermediaries.  In order to support WS-Addressing you need to set a few advanced properties in SOAPUI which aren’t enabled by default when you generate your project from a WSDL.
The first thing you need to do is focus on your request message and click on the WS-A (at least that is what it is called in SOAPUI 3.6) tab as highlighted in the below screenshot.
You now need to ensure that you’ve checked the tickbox against Enable/Disable WS-A addressing, set the Must understand dropdown box value to True, and ticked the Add default wsa:To tickbox as highlighted in the below screenshot.
If you call on the service now that should work (assuming you don’t have any security turned on for the service, you might need to apply more advanced settings to enable this).
Do also note that if you choose to use Message based security and you enable the Establish Security Context tickbox (the below screenshot is from a BizTalk WCF-WSHttp send port) then you will always get a failure from SOAPUI like the following – “The message could not be processed. This is most likely because the action xxx is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint’s binding.”  This happens because SOAPUI doesn’t appear to support this setting, you will need to turn it off while you are testing from SOAPUI or use an alternative testing tool.

Monday, February 18, 2013

Is there a difference between “throw” and “throw ex”?


Throw: It propagates the full stack information to the caller,
                      When you use the throw with an empty parameter, you are re-throwing the last exception. Or rethrows the original exception and preserves its original stack trace.
Sample:


static void Main(string[] args)
{
  try
  {
     Method2();
  }
  catch (Exception ex)
  {
     Console.WriteLine(ex.StracTrace.ToString());
     Console.ReadLine();
  }
}

static void Method2()
{
  try
  {
     Method1();
  }
  catch (Exception ex)
  {
     throw;
  }
}

static void Method1()
{
  try
  {
     throw new Exception ("This is thrown from Method1");
  }
  catch (Exception ex)
  {
     throw;
  }
}

Throw ex:

Sample:


static void Main(string[] args)
{
  try
  {
     Method2();
  }
  catch (Exception ex)
  {
     Console.WriteLine(ex.StracTrace.ToString());
     Console.ReadLine();
  }
}

static void Method2()
{
  try
  {
     Method1();
  }
  catch (Exception ex)
  {
     throw ex;
  }
}

static void Method1()
{
  try
  {
     throw new Exception ("This is thrown from Method1");
  }
  catch (Exception ex)
  {
     throw;
  }
}




Summary:


Reference link : http://dotnetinterviewquestion.wordpress.com/2012/06/06/c-training-difference-between-throw-and-throw-ex/

Monday, December 10, 2012

BizTalk 2013 Intorduction

http://blogs.msdn.com/b/biztalk_server_team_blog/archive/2012/11/06/announcing-biztalk-server-2013-beta.aspx
http://biztalkadmin.com/biztalk-2013-sql-2012-and-server-2012/
http://www.zdnet.com/microsofts-biztalk-2013-enterprise-integration-server-hits-beta-7000007054/

Thursday, December 6, 2012

Can we do method overloading in WCF services


The soap xml not support OOPs and WCF generate proxy and it'll not follow method overloading.
Inside the WCF service code it'll allow us Method Overloading.

By default overload operations (methods) are not supported in WSDL based operation. However by using Name property of OperationContract attribute

Sample:
[ServiceContract]
public interface IService1
{
[OperationContract(Name="GetData")]
string GetData(int value);

[OperationContract(Name="GetData1")]
string GetData(int value, int value1);

}

public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}

public string GetData(int value, int value1)
{
return string.Format("You entered: {0}, {1}", value, value1);
}
}

Notice that both method name in the above interface is same (GetData), however the Name property of the OperationContract is different. In this case client proxy will have two methods with different name GetData() and GetData1().

Wednesday, November 28, 2012

Accessing Application Configuration Settings from SQL CLR


In some (most?) cases we don’t want to hard-code connection details. In this case it means the path to the web service. Imagine a situation where you are consuming a web service that you’ve developed yourself, or another team in your company. And the web service is running in several environments: development, acceptance, production. Of course we don’t want to change our code and recompile each time we need to deploy to a different environment. So we need a way to configure the web service location.
The answer here lies in the sqlservr.exe.config file. This is a file like any other .config file, with a possible content like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="MyWebService" value="http://MyWebServiceServer:MyWSPort/PathTo/MyWebService.asmx" />
  </appSettings>
</configuration>


This file needs to be put in the same folder as your sqlservr.exe that’s running your SQL Server instance.  By default this path is C:\Program Files\Microsoft SQL Server\MSSQL.1\{MSSQL10_50.MSSQLSERVER}\Binn\.  When you restart your SQL Server instance while this file is in that folder, SQL Server will pick up any configuration settings from that file.  These can then be accessed from your custom stored procedure in this way:
MyWebService myWS = new MyWebService();
myWS.Url = ConfigurationManager.AppSettings["MyWebService"];
myWS.MyWebMethod();


One of the issues I encountered (a bug) is if the first call through ConfigurationManager is to the static AppSettings method an error is returned indicating it couldn't read the key value. That error is:
"The value of the property 'key' cannot be parsed. * The error is: Request failed. (sqlservr.exe.Config line X)".
Now, the line that causes this exception is:
ConfigurationManager.AppSettings["MyWebService"]

There’s absolutely nothing wrong with that line of code. And, there’s nothing wrong with the configuration file.
So, after some debugging, I found that if I make some “dummy” call through ConfigurationManager to another method, then I can make the call to AppSettings with absolutely no issue. So, the following line is added just to provide a kludge of a workaround :
int firstcall = ConfigurationManager.ConnectionStrings.Count;

Now, this line does nothing other than initialize ConfigurationManager and force a de-serialization of the configuration file.
int firstcall = ConfigurationManager.ConnectionStrings.Count;

MyWebService myWS = new MyWebService();
myWS.Url = ConfigurationManager.AppSettings["MyWebService"];
myWS.MyWebMethod();




Tuesday, November 27, 2012

Steps to Create SQL CLR component


1. Let’s start with creating our .NET assembly with the custom stored procedure.  Using Visual Studio 2010, create a new Database Project:


2. First, you must change the version of the.NET Framework used to 3.5 at the top of this screen or your project will not deploy. Then change the project name to MyExtendedDBFunctions


Add a reference to the Your (AdventureWorks) database by clicking Add New Reference.


    Fill out the form and click OK.


3. Select AdventureWorks and click OK. Then right click the solution in Solution Explorer and select New -> Stored Procedure


Change the name to TestUserDefinedFunction.

Change the code to look like this:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class TestUserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
   public static SqlString TestUDF(int number)
   {
    BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
   EndpointAddress endpoint2 = new EndpointAddress(new Uri("http://localhost:51610/TestService2.svc"));
    TestService2Client client2 = new TestService2Client(basicHttpBinding, endpoint2);
       return new SqlString(client2.GetData(internalID));    
   }
};




Create a WCF service with the default .net Framework 4.0 and expose that service and use the existing GetData().

4. Before we build our assembly there are a couple of project settings that need modification.
Here we ask Visual Studio to also generate an assembly containing the XML Serializers.  This is needed because our code is calling a web service and code running in SQL Server is not allowed to use the serializers that are normally generated dynamically.


5. Another setting that we need to change is the Permission Level.  This is also required because our code is calling a web service, hence UNSAFE.


6. Server and Database Settings


USE custDB
EXEC sp_configure 'clr enabled', '1';
RECONFIGURE;
ALTER DATABASE custdb SET TRUSTWORTHY ON;

-- Adding System.Web assembly

CREATE ASSEMBLY [System.Web]
FROM  'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dll'
WITH PERMISSION_SET = UNSAFE


CREATE ASSEMBLY  [System.SMdiagnostics]
FROM 'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\SMdiagnostics.dll'
WITH PERMISSION_SET = UNSAFE
GO

-- Adding required assemblieds for the WCF service.
CREATE ASSEMBLY  [System.IdentityModel]
FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.dll'
WITH PERMISSION_SET = UNSAFE
GO

CREATE ASSEMBLY  [System.IdentityModel.Selectors]
FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.Selectors.dll'     
WITH PERMISSION_SET = UNSAFE
GO

CREATE ASSEMBLY  [System.Messaging]
FROM  'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll'     
WITH PERMISSION_SET = UNSAFE     
GO

--Attempted to perform an operation that was forbidden by the CLR host.

CREATE ASSEMBLY  [Microsoft.Transactions.Bridge]
FROM  'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\Microsoft.Transactions.Bridge.dll'     
WITH PERMISSION_SET = UNSAFE     
GO



7. Click Build -> Deploy Solution and you should receive the following output:

If deploy failed, please follow below steps to add your CLR component and procedure/function to the sql server

Register our SQL CLR component

IF EXISTS (SELECT [name] FROM sys.assemblies WHERE [name] = N'MyExtendedDBFunctions')
BEGIN
     DROP ASSEMBLY [MyExtendedDBFunctions]
ALTER ASSEMBLY MyExtendedDBFunctions
FROM '{our SQLCLR project.dll path}'
WITH PERMISSION_SET = UNSAFE ;
END
ELSE
BEGIN
CREATE ASSEMBLY MyExtendedDBFunctions
FROM '{our SQLCLR project.dll path}'
WITH PERMISSION_SET = UNSAFE;
END

Once our assemblies are created we have to create Procedure/Function in the below way.

CREATE PROCEDURE WeatherSP
    @zipCode nvarchar(10)
AS EXTERNAL NAME MyStoredProcedures.StoredProcedures.WeatherSP;
GO

CREATE Function TestSP(@name nvarchar(10)) returns nvarchar(150)
AS EXTERNAL NAME MyExtendedDBFunctions.TestUserDefinedFunctions.TestUDF;

Below are the possible errors and solutions 
1. Attempted to perform an operation that was forbidden by the CLR host.
    Sol: Set PERMISSION_SET to UNSAFE Because EXTERNAL_ACCESS did not work for us.
2. The type 'Microsoft.VisualStudio.Diagnostics.ServiceModelSink.Behavior, Microsoft.VisualStudio.Diagnostics.ServiceModelSink, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' registered for extension 'Microsoft.VisualStudio.Diagnostics.ServiceModelSink.Behavior' could not be loaded. (C:\Windows\Microsoft.NET\Framework\v2.0.50727\Config\machine.config line 233)

    Sol: Note that everything is configured properly and WCF client inside stored procedure should initialize just fine. The problem is somehow connected to machine.config file or better, to some initialization of types defined there.
          Looks like the exception is linked to WCF debugging feature, usually installed on development machines - this debugging service has problems with WCF client running under SQL Server.
         
        Workaround: (Temporary) disable WCF debugging by invoking this command line utility:
        [Program Files]\Microsoft Visual Studio 9.0\Common7\IDE\vsdiag_regwcf.exe -u
        Now the WCF client inside SQL Server runs just fine. After you've done you can re-enable WCF debugging 
services by calling same exe with different parameter:
       [Program Files]\Microsoft Visual Studio 9.0\Common7\IDE\vsdiag_regwcf.exe -i

Note that administrator privileges are required to disable/enable it.