Action Filter in WebApi 2

Its been a while I haven’t blogged for sometime. To create an action filter in Web Api 2 and return the response directly you can use the code below

public class StepUpAttribute : ActionFilterAttribute
{
public IUserFactory CurrentUser { get; set; }

public override void OnActionExecuting(HttpActionContext filterContext)
{
if (CurrentUser.IsSteppedUp)
return;

// stop request process and return
filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.OK,
ErrorResponseFactory.FromUnsafeActionDetectedResponse(),
filterContext.ControllerContext.Configuration.Formatters.JsonFormatter);

}
}

Exporting Excel to XML: A mapped element’s relationship with other elements cannot be preserved

I have an Excel file that need to be exported into XML. I have a few files to be converted. One of them was complaining when I’m about to export it to XML and it throws an error of "A mapped element’s relationship with other elements cannot be preserved". Spend quite a few hours try to google it out and fix it but with no luck. So what I did to resolve this issue "Convert the excel into CSV and then open the CSV with Excel and applied my XSD and export it to XML again and it works fine!!"

Remove Folder on the Release Mode using MSBuild

I got this code snippet to remove "TestHarness" folder only on the Release Mode but when I publish it on the "Debug" Mode the folder should still be there. It is a simple code but it took me a while to figure it out

My csproj file

<ItemGroup>
<ExcludeFromPackageFolders Include="TestHarness" Condition=" ‘$(Configuration)’ == ‘Release’">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFolders>
</ItemGroup>

Fusion Log – Assembly Logging

Another helpful debugging tool that can be used is FusionLog – it is already installed in your machine by default and what this tool does is basically logging and telling us where the assembly is loaded from either local or GAC or some other location and at the same time it tells you it couldn’t locate the assembly

-First create a folder called “FusionLog” on C drive or any location with any name

-Open your Regedit to add the key below

HKEY_LOCAL_MACHINESOFTWAREMicrosoftFusion

Add:

DWORD ForceLog set value to 1

DWORD LogFailures set value to 1

DWORD LogResourceBinds set value to 1

String LogPath set value to folder for logs (e.g. C:FusionLog)

Make sure you include the backslash after the folder name and that the Folder exists.

-Restart your computer

-Run your application

-Look the assembly name from c:fusionlog

-Open the file and it will tell you where the assembly is loaded from

Table Valued Parameter – SQL Server 2008

Simple sample in how to use Table Valued Parameter which is a new feature in SQL Server 2008. I found it very useful to pass bulk data from one SP to another SP

CREATE TYPE JobQueueBroker AS TABLE (JobID INT NOT NULL, UpdateDate DATETIME DEFAULT(GETDATE()))
GO

CREATE PROCEDURE [dbo].[Jobs_JobX_SubmitQueueBulk]
@Jobs JobQueueBroker READONLY
AS

BEGIN
DECLARE @Message XML

SELECT @Message = ( SELECT * FROM @Jobs
FOR XML PATH(‘Job’),
TYPE
);

— Above will fomulate valid XML message
DECLARE @Handle UNIQUEIDENTIFIER ;

— Dialog Conversation starts here
BEGIN DIALOG CONVERSATION @Handle FROM SERVICE ServiceJobXJobFinishedProcessing TO SERVICE ‘ServiceJobXJobUpdate’ ON CONTRACT [JobContract] WITH ENCRYPTION = OFF ;
SEND ON CONVERSATION @Handle MESSAGE TYPE JobDetails (@Message) ;

END
GO

DECLARE @Jobs JobQueueBroker
INSERT @Jobs VALUES (1, GETDATE())
INSERT @Jobs VALUES (2, GETDATE())
INSERT @Jobs VALUES (3, GETDATE())
EXEC dbo.[Jobs_JobX_SubmitQueueBulk] @Jobs
GO

Mapping Local Drive to other Drive path

Just in case if in your development environment has a hardcoded drive mapping path in your config file and you don’t have the drive exists in your local

The workaround is run the command below

C:\Windows\System32\SUBST D: C:\

And run SUBST after to confirm

And then you can access it in command line and mapped it in TFS will work as well BUT it won’t appear on Windows Explorer.

Shutdown your computer will remove this virtual mapping. So I recommend you to create a BATCH file and put it as startup (you can put the batch file on this location "C:\Users\{User Profile}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup")

MERGE Insert, Update and Delete SQL Server

In SQL Server 2008, we can do a table synchronisation in one transaction of SQL Command. For example normally, we have a source table and then we have an updated records and what we would like to do is "I want to delete the record from the source table if it is not in my updated list, if there is a matched record then I’d like to update the value to the latest value, and if the record is not exists at all on the source table then I’d like to insert it"

I got a sample query with the recordset and syntax below in how to use "MERGE" to handle the case above. I got the actual sample code from (http://www.mssqltips.com/sqlservertip/1704/using-merge-in-sql-server-to-insert-update-and-delete-at-the-same-time/) – by Arshad Ali

IF EXISTS(SELECT 1 FROM sys.tables WHERE NAME = ‘Products’)
BEGIN
DROP TABLE Products
END
GO
CREATE TABLE Products
(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100),
Rate MONEY
)
GO
–Insert records into target table
INSERT INTO Products
VALUES
(1, ‘Tea’, 10.00),
(2, ‘Coffee’, 20.00),
(3, ‘Muffin’, 30.00),
(4, ‘Biscuit’, 40.00)
GO
SELECT * FROM Products
GO
–Create source table
DECLARE @UpdatedProducts TABLE
(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100),
Rate MONEY
)
–Insert records into source table
INSERT INTO @UpdatedProducts
VALUES
(1, ‘Tea’, 10.00),
(2, ‘Coffee’, 25.00),
(3, ‘Muffin’, 35.00),
(5, ‘Pizza’, 60.00)

SELECT * FROM @UpdatedProducts

MERGE Products AS TARGET
USING @UpdatedProducts AS SOURCE
ON (TARGET.ProductID = SOURCE.ProductID)
–When records are matched, update
–the records if there is any change
WHEN MATCHED AND TARGET.ProductName <> SOURCE.ProductName
OR TARGET.Rate <> SOURCE.Rate THEN
UPDATE SET TARGET.ProductName = SOURCE.ProductName,
TARGET.Rate = SOURCE.Rate
–When no records are matched, insert
–the incoming records from source
–table to target table
WHEN NOT MATCHED BY TARGET THEN
INSERT (ProductID, ProductName, Rate)
VALUES (SOURCE.ProductID, SOURCE.ProductName, SOURCE.Rate)
–When there is a row that exists in target table and
–same record does not exist in source table
–then delete this record from target table
WHEN NOT MATCHED BY SOURCE THEN
DELETE;

SELECT * FROM Products

GO

REST API Versioning

There are a couple of ways in versioning your API

1. Through REST URL . domain.com/v1/Customers, domain.com/v2/Customers

2. Through HTTP Header – add the version as part of Content-type

3. Add the version on the REST object itself as one of the attribute/property

A few excellent articles:

http://stackoverflow.com/questions/389169/best-practices-for-api-versioning
http://codebetter.com/howarddierking/2012/11/09/versioning-restful-services/