WEBDEPLOY: ENABLE TRACING

Lately I have been spending some *Quality* time with MsDeploy aka. Web Deploy and Often deploying sites to Remote Agent requires understanding what is going on under the hood when problem occurs. Like any production application, enabling tracing helps out immensely when things does not seem to work the way you think it should work.

Here are couple of switches that will help you see what is going on.

Caution: It is registry right? so back it up

reg add “HKLM\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\3” /v EnabledTraceLevel /t REG_DWORD /d 2 /f

reg add “HKLM\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\3” /v WMSVCTracing /t REG_DWORD /d 1 /f

Web API: Introduction to SystemDiagnosticsTraceWriter

Today ASP.NET Team released 2012.2 update. One of the cool features is the support for .NET Native tracing capability.

The idea is all the trace information that is available while request flows through message handlers and formatters and find their way to the controller is now available now for you to consume.

For users starting on New Project with this update installed, this feature will be turned on automatically. See line config.EnableSystemDiagnosticsTracing in the snippet below

config.enable

How does it work?

Let’s say you have a controller called “Values” and you do http://localhost/Webapi/api/Values. When you run it in visual studio, You get this by default in tracing window of VS. Here you find all the information that passed through various layers of WebAPI pipeline.

vs.trace.output

Now what if I want this output to be redirected to say console? It is extremely simple. Just throw this in your App.Config or Web.Config file.

Below, I’m adding ConsoleTraceListener for my Console App project. (You can add file or other tracelisteners if you like)

diagnostic.config

The output is as following and it is directed to console now.

console.trace.output

That’s cool but what about internal stuff?

This whole magic is achieved when you do config.EnableSystemDiagnosticsTracing() via an extension method. Internally it looks like this.

internal_trace

SystemDiagnosticsTraceWriter is the class which makes this possible.

Here the extension method creates an instance of SystemDiagnosticsTraceWriter and then uses an extensibility feature of WebAPI to provide the implementation for ITraceWriter.

This implementation lives in an assembly called System.Web.Http.Tracing.dll which is also available as nuget package.

If you are working with earlier versions of WebAPI and cant upgrade, then just download the nuget package and then just provide implementation of ITraceWriter manually.

Web API–How to change Default Serializer settings

Out of box, Web API provides a way to serialize using JSON and XML.
In this blog post, I will describe how you can control JSON settings for the default serializer.

JSON Settings.

e.g Say you want your date to be formatted as per Microsoft format as opposed to ISO standard (for whatever reason).
All you do is get hold of the jsonFormatter and then use SerializerSettings to set DateFormatHandling.

JsonDateFormatCode

ISO Date Format for JSON

isoFormat

Microsoft Date Format for JSON.

microsoftdateFormat

By default, Json.NET will use ISO format for your date time format serialization

WebAPI: Calculating NextPageLink for ODataResult<>

Fall update of Web API introduced ODataResult<> which is used to implement OData features like Server Driven Paging and $inlinecount. I blogged about it here 

If you look at the definition of ODataResult<>, it has following properties,

1. Items Collection
2. NextPageLink property
3. Count

Essentially calculating Items and Count are no brainer once you have access to IQueryable however NextPageLink can be interesting as there is no default implementation.

In this post, I’m going to describe how to calculate NextPageLink property. Feel free to modify the code as per your requirement, it is merely one way of achieving the goal.

Basics:

If you think about Paging support, you are thinking of two possible parameters, Batch Size & Page Number.

Usually queries are done like pageNumber=1 & batchSize=2 for first page, pageNumber=2 & batchSize=2 for the next page and so on, resulting in request made for page from 1..N but your batchSize does not change.

Here is the complete code sample which shows you how to calculate the NextPageLink.

 public static Uri CalculateNextPageLink(
            HttpRequestMessage request,
            int resultLimit)
        {
            if (resultLimit <= 0)
            {
                return null;
            }

            int topValue;
            int skipValue;

            var topValueRaw = request.GetQueryNameValuePairs()
                                     .FirstOrDefault(x => x.Key == "$top");
            if (!Int32.TryParse(
                topValueRaw.Value,
                out topValue))
            {
                return null;
            }

            var skipValueRaw = request.GetQueryNameValuePairs()
                                      .FirstOrDefault(x => x.Key == "$skip");

            if (!Int32.TryParse(
                skipValueRaw.Value,
                out skipValue))
            {
                return null;
            }

            if ((topValue > resultLimit) || (topValue <= 0 || skipValue < 0))
            {
                //return the same url
                return null;
            }

            //logic
            //skip=pageIndex*pageSize
            //top=pageSize
            var stringBuilder = new StringBuilder();
            var bothSkipAndTopSupplied = (topValue != -1 && skipValue != -1);
            var lastPageIndex = skipValue/topValue;
            //int lastPageNumber = lastPageIndex+1;

            foreach (var keyValue in request.GetQueryNameValuePairs())
            {
                switch (keyValue.Key)
                {
                    case "$top":
                        stringBuilder.AppendFormat("$top={0}",(bothSkipAndTopSupplied)? topValueRaw.Value: keyValue.Value);
                        break;
                    case "$skip":
                        if ((bothSkipAndTopSupplied))
                        {
                            stringBuilder.AppendFormat("$skip={0}",((lastPageIndex + 1)*topValue));
                        }
                        else
                        {
                            stringBuilder.AppendFormat("$skip={0}",keyValue.Value);
                        }
                        break;
                    default:
                        stringBuilder.Append(Uri.EscapeUriString(keyValue.Key));
                        stringBuilder.Append("=");
                        stringBuilder.Append(Uri.EscapeDataString((keyValue.Value)));
                        break;
                }

                stringBuilder.Append("&");
            }

            stringBuilder.Remove(
                stringBuilder.Length - 1,
                1);

            return new UriBuilder(request.RequestUri)
            {
                Query = stringBuilder.ToString()
            }.Uri;
        }

Introducing NLog to SignalR

{  NLog+SignalR+Toastr==NLogToSignalR }

I have created a simple NLog target which uses SignalR (calling it NLogToSignalR) under the covers and delivers the log to either Hub or PersistentConnection and deliver nice messages using toastr.

Where does it fit?

Schematic

Purpose

If you use NLog as a logging tool, you can use this to deliver log messages to either same (or remote server) in real time in true toastr style

e.g. Information can be displayed as

Information

Warning

Warning

Error

Error

How does this work?

You need follow these steps:

1. Put NLog.Targets.SignalR in the same folder as your App.Config/ Web.Config file

2. If you are going to be using Hub for SignalR, use following configuration

nlogconfig

3. Deploy the Server NLog.Targets.SignalR.AspNetServer on local IIS.

4. Browse the website after deployment. (Ensure .NET Framework 4.5 is installed)

5. Start logging and watch the logs in real time.

The code is available for download from github.

Enjoy!

Web API Fall Update – ODataResult<T>

Another great feature  Web API team has provided support for Server side paging and $inlineCount is called oDataResult<T>

It is really easy to achieve this. Earlier you could return the data but you will have to rely on other mechanisms to achieve $inlineCount.

Step1: Change your return type of the controller action to oDataResult<T>.

Assuming your resource is available at

http://localhost:8080/webapi/Accounts.

image1

Step2: Execute the request.

image2

Now you can get the count and a navigation path both.