Archive for the ‘WCF’ Category

Enable Trace for a WCF service

Posted: January 20, 2017 in WCF

Introduction:

Capturing Logs in an application (server /client side) helps in analyzing and identifying any issues.  Especially it is very helpful when an issue occurs only on Test/Production environments which can’t be duplicated on local developer machines.  

Sometimes, there could be issues at low/framework level.  In those scenarios,  application level logging is also not much helpful as exception might happen even before hitting the initial break point in the application/developer code.  The same is true for a WCF service as well.

In such cases, we could enable WCF service tracing which logs all the steps in WCF request/response pipeline.

Creating a WCF test service and deployment:
Create a simple WCF service and host it on IIS.  Refer this article for more details.

Update web config:

Now we make few changes to web.config. Open the web.config of WCF project and make following changes:

1) Add following diagnostics section in the config file.  Here we are adding listeners and also telling the location to write the log file.  Update the log file path (initializeData) according to folder structure in your machine.

<system.diagnostics>
    <trace autoflush="true" />
    <sources>
        <source name="System.ServiceModel" switchValue="Information, ActivityTracing">
        				<listeners>
          <add name="xml"/>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        				<listeners>
          <add name="xml"/>
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData= "C:\logs\WCFDiagnosticsExample.svclog" />
    </sharedListeners>
</system.diagnostics>

2) Add following configuration inside serviceModel section.

 <system.serviceModel>
     <diagnostics>
      <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="3000" />
     </diagnostics>

Call the WCF service:

Open WCFTestCient and add test service (defined above).  Make a service call using Invoke button.

Once you invoke a method on WCF test service, you should be seeing a log file generated at specified location.   If you observe the size of the file, it may be zero.  That means the log entries are not yet flushed out.  Stop the web application on IIS manager.  Then the log contents will be written to the file.

Service Trace Viewer:

There is a tool called Service Trace Viewer from Microsoft to view the contents of the log file (*.svclog).  To open the tool, open windows explorer and go to following location.   The version folder names may vary depending on what version is installed in your machine.

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools
Note: If you don’t see SDK folder, then you need to install Microsoft Windows SDK.

servicetrace

Note: If your wcf service is not hosted by IIS and you have a self host application, then you need to run the app in admin mode to grant permissions to the logging path.

In this article I would like to discuss on hosting a WCF service in IIS.

Create a WCF service application:

As a first step, create a  WCF service application.   From Visual Studio, go to File -> New -> Project.  Select ‘WCF Service Application’ under WCF in templates window.

The following components will be present in the newly created project:

  •         App_Data folder
  •         IService1.cs interface
  •         Service1.sbc and Service1.svc.cs files.  You can rename the interface and service files.
  •         Web.config file.

The Service1 class is defined with following two service methods and I don’t make any changes rather I would use it as it is.

  •         GetData
  •         GetDataUsingDataContract

Now we need to add end points for the service.  Go to web.config file and add following configuration under System.ServiceModel section.  Replace Contract and Service names according to your service namespace and class names.

<pre><system.serviceModel>
	<services>
  	<service name="MyTestService.Service1" >
    	<endpoint address="" binding="basicHttpBinding" contract="MyTestService.IService1">
    	</endpoint>
    	<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  	</service>
    </services>
…

 

Host WCF service in IIS:

Run inetmgr command from Start -> Run to open IIS.
Right click on Sites and select Add Website. Enter Site name.

Service

Note: When you add a new Website, by default it creates a new application pool. You may assign it to an existing pool. The newly created pool may be configured with .Net V2.0. So go to Application Pools in IIS and double-click on newly created application pool. If it is pointing to older .Net versions then select appropriate framework version (in our case, the web application is created with .net V4.0 in first step).
Now try to access the service and we should be able to access service metadata. The URL should be similar to following:
http://localhost/Service1.svc

We can use WCF Test Client tool to test your service.

Introduction:
In this post I would like to discuss about writing Unit Tests for BLL components which uses EF for DB operations. My intension here is not to focus on writing tests for DB CRUD operations but to test business logic which involves retrieving further details from Database using EF to validate business scenarios. For these scenarios, either BLL component has to get data from Database or we need to explicitly provide some kind of sample data/objects so that validations can be done against of these objects.

Following are few of the different ways for doing this:

Using SQL Server Compact Edition(SQL CE):
SQL CE database can be created dynamically (.sdf file on disc) and data can be populated using SQL CE schema/sample data scripts. SQL Server scripts don’t work with SQL CE. Using SQL Server Compact Tool we can generate SQL CE compatible Schema/sample data scripts.
Here is the code snippet how to programmatically create CE database. System.Data.SqlServerCe reference has to be added to the project.
Connection String can be defined as shown below:

strConnString = “Data Source=” + CE_DB_FilePath_OnDisk;

SqlCeConnection objConn = null;
objConn = new SqlCeConnection(strConnString);
string[] arrCommands = strDatabaseSchema.Split(new string[] { m_strCommandSeparator }, StringSplitOptions.RemoveEmptyEntries);
SqlCeCommand objCmd = new SqlCeCommand();
objCmd.Connection = objConn;
objConn.Open();

foreach (string strCmd in arrCommands)
{
    string strTrimmedCmd = strCmd.Trim();
    if (!String.IsNullOrEmpty(strTrimmedCmd))
    {
        objCmd.CommandText = strTrimmedCmd;
        objCmd.ExecuteNonQuery();
    }
}

Once we create the CE Database, we can create context by passing connection string.

Public class LibraryContext : DbContext
{
    public LibraryContent()
           : base("LibraryDBConnection")
    {
    }
}

Connection string can be configured in .config file.

<connectionStrings>
    <add name=" LibraryDBConnection "
         providerName="System.Data.SqlServerCe.4.0"
         connectionString="Data Source=|DataDirectory|LibraryDb.sdf"/>
</connectionStrings>

Pros:
SQL CE is in memory/file IO based and doesn’t require installation of SQL. So these tests can be executed on build agents on TFS without any additional SQL pre-requisites.
It is a sample database which is a replica of production Database, so most of the business logic scenarios can be covered.

Cons:
The issue with this approach is, we can’t create single DBContext which serves both SQL Server and SQL CE using same model (.edmx) due to following reasons:
SQL server model uses “System.Data.SqlClient” provider whereas SQL CE expects “System.Data.SqlServerCe.4.0”

Provider=”System.Data.SqlClient”
ProviderManifestToken
EntitySet contains Schema=”dbo” however this is not applicable for SQL CE.
SQL CE limitations such as it doesn’t support Stored Procedures, Views, Triggers

Mocking DB context:
Using Moq framework we can have in-memory implementations for DB context and can be used for unit tests.
For example we have a simple model for Novels and Magazines. The context and interface looks like as shown below:

Public interface ILibraryContext
{
    DbSet Books { get; set;}
	DbSet Magazines { get; set;}
	void SaveChanges();
}

Public class LibraryContext : DbContext, ILibraryContext
{
	Public DbSet Books { get; set;}
	Public DbSet Magazines { get; set;}
	Public void SaveChanges()
    {
        //…
    }
}

Now we can mock the context.

_context = new Mock< ILibraryContext>(MockBehavior.Strict);

We need to Setup the methods which are used while testing the actual methods.

_context.Setup(c => c.SaveChanges()).Returns(LocalSaveMethod);

Implement some sample method for save.
We also need to setup objects. Objects setup requires corresponding object data.

_bookData = new List
            {
            new Book(), new Book()
};
_context.Setup(c => c. Books).Returns(PopulateBooksMockSet);

Private IDbSet PopulateBooksMockSet()
{
    Mock<IDbSet> _booksMockSet = new Mock<IDbSet>();
    _ booksMockSet.As().Setup(
        m => m.Provider).Returns(_bookData.AsQueryable().Provider);

    _ booksMockSet.As<IQueryable>().Setup(
        m => m.Expression).Returns(__bookData.AsQueryable().Expression);

    _ booksMockSet.As<IQueryable>().Setup(
        m => m.ElementType).Returns(__bookData.AsQueryable().ElementType);

    _ booksMockSet.As<IQueryable>().Setup(
        m => m.GetEnumerator()).Returns(__bookData.AsQueryable().GetEnumerator());
    return _ booksMockSet.Object;
}

Say the following is the BLL method which we wanted to test.


public void UpdateBookName(ILibraryContext context, Book bookObj, string newName)
{
    var bookInstance = context.Books.Where(b => b.Id == bookObj.Id).FirstOrDefault();

    if (bookInstance != null)
    {
        bookInstance.Name = newName;
        context.Books.Attach(bookInstance);
        context.SaveChanges();
    }

}

The typical test case would look like this:


[TestMethod]
public void UpdateName_Test()
{
     string newName = "Updated name";
     UpdateBookName(context, bookObj, newName);

     Assert.AreEqual(bookObj.Name, newName, "Name not updated");
}

Now how do we test delete object scenarios.
Generally, when we call context.Remove(object), the object doesn’t get removed from collection instead the object state will be changed to deleted state. When we call context.SaveChanges(), the ojects which are in deleted state will get removed/deleted. With mocking context, saveChanges is a dummy operation.
To test this scenario, we can use Mock<IDbSet<>>. Using Mock sets, We can check if a method was called with a particular parameter or not. We can also check how many times it was called.

bookMockSet.Verify(m => m.Remove(deletedBook), Times.Once(), “Book is not deleted”)

Pros:
Mocking DbContext works with in memory objects hence it would be faster.
It doesn’t have any addition overhead such as installation/setup etc.

Cons:
Though we have in memory context it is not equal to DbContext. It uses “LINQ to objects” compared to “LINQ to Entities” which EF actually does.
Creating mock objects (sample data/objects) is tedious.
Though it has such limitations, it can provide a good level of unit test coverage for EF.

Using SQL Express instance:
Create a separate Database programmatically on SQL express instance and populate sample data for every time when a test is executed. Delete the Data at the end of Test execution, so that the data can be repopulated next time when another test is executed. This is more like an integration testing than unit testing.

Pros:
It is a full blown end to end testing.
It doesn’t have any other maintenance overhead such as creating sample shema/data

Cons:
This makes SQL express installation as pre-requisite for build agents on TFS.

Please provide your valuable feedback/comments/suggestions that will help me improve my writing.

Introduction:

An app for Office is basically a webpage that is hosted inside an Office client application.  It enables users to run the same solutions across applications, platforms and devices.  The applications are developed by using the powerful web technologies such as HTML5, XML, CSS3, JavaScript and REST API’s.    Refer MSDN documentation on Office Apps for more details.

The three basic types of Office apps are task pane, content and mail apps.  In this article I am going to explain how to develop an Office 2013 Excel Task pane app that acts as a live data work book.  The app will have following functionalities:

  • Communicating with an external WCF service to fetch live data
  • Write data into excel work sheet from Task pane app.
  • Track data modifications in excel work sheet.
  • Save modifications to Database through WCF service.

pic1

Connecting to a WCF data service:

Here I am going to start with WCF communication part.  However if you are looking for instructions on how to create a basic Excel task pane app, please refer MSDN.  The task pane app can communicate with an external WCF data service in following ways:

  1. Office Client (JavaScript) to External WCF service
  2. Web Service to WCF Service

1)     Office Client (JavaScript) to External WCF data service:

In this approach the communication part is written in java script, which is executed at client side.

Use JQuery to communicate with WCF data service as shown below.    The first step is construct an URI which should be understandable to WCF Data service.  Writing complex URI queries is tricky however a tool called LINQPad can be used for URI construction.  In this example Dataservice is hosted at http://localhost:17203/MyService end point.

pic2

One of the major issue with java script client side communication is same-origin policy limitation.  Generally browsers don’t allow clients talking to servers which are not in same domain.  One of the way to overcome this issue is enabling CORS.  The following setting will do that.

$.support.cors = true;

Tip: When you add a project of type “Office 2013 App”, visual studio creates a web project for you for developing UI for the app.   If you run app in debug mode from Visual Studio, the web project will be hosted on IIS Express on SSL.  In that case, above code may throw following exception “Access denied”.  To resolve this issue, host the web application on IIS (basic http) or use a self-hosted Web service.

The other approach is using JayData. JayData library comes with a utility called JaySvcUtil.exe which can be used to generate a context file in java script.  Use following command to generated the context file.pic3

Once context.js file is created, add it to the project.  Below is the command to generate java script context.

Tip: WCF data service by default enables metadata on $metadata end point.  So make sure to append ‘$metadata’ to the service end point while generating context.

pic4

Generating static context with JaySvcUtil.exe may have maintenance issues.  Whenever service contracts are changed we need to regenerate proxy and add it to the project.  We can avoid that by creating context dynamically with following command.

pic5

Another approach is to use JasonP. I am not covering this topic here however it can be used to resolve Cross domain communication issues.

2)     Web Server to WCF Service:

As mentioned earlier, due to same-origin policy limitations we may encounter issues like ‘Access Denied’ exceptions while trying to communicate with external WCF service in java script.  So this is an alternate approach to overcome that issue.

The communication happens in two steps in this approach:

Office Client <-> Webserver (server side Code) <-> External WCF service

Office client (java script) calls a Web Method which is executed at ASP server side.  Then Web Service makes a call to WCF service.  Here are the steps to achieve it.

Add a service reference (using WCF data service end point) to the project.  Add an ASP .Net page to the project.  Go to the class in aspx.cs file and write following lines of code.

pic6

We are creating a context using Service reference by specifying the service end point. In this example it returns a list of accounts.   Make sure the method is decorated with WebMethod attribute so that it can be accessed from client’s JavaScript.  Using PageMethods we can call the server side method as shown below.

pic7

Writing data into Excel sheet:

Till now we have focused on WCF service communication and fetching the data from service.    Now we are going to see how we can populate the excel sheet with the data.  setSelectedDataAsync method is used for writing data into excel sheet in selected location. This is defined in Office JavaScript library.  We can write data in 3 formats such as matrix, table, and text.  I will use table data type so that we can display headers along with data.  First create table data. In below example, ‘res’ is the collection which is received from WCF service.  First we specify the headers and then push the data rows.

pic8

Now write the table data in excel sheet at current selection.  Most of the Office java script library methods are asynchronous so that it doesn’t block the Excel interaction with end user.

pic9

Tracking changes in the excel sheet:

Now we want to track changes made by user in excel sheet so that modifications can be automatically sent to WCF service for saving them in Database.  We can use databindings and datachanged event hanlder.

Office.context.document.bindings is a collection of bindings specific to the document.  Add a new binding to this collection and specify the type as table data.  On success, we can add a handler of type ‘BidningDataChanged’.  When data is changed we receive a parameter called eventArgs.   We can use eventArgs.binding.getDataAsync method to reading current data from excel.  One of the drawback with datachanged is, it doesn’t specify what is changed.  It could be an update to a cell or addition/deletion of new row/column, so we need to write custom logic to identify the change and act on it accordingly.

pic10

Please provide your valuable feedback/comments/suggestions that will help me improve my writing.