JavaScript CORS used to call asmx web-services

The following example shows how to implement a server implementing an asmx web-service and a JavaScript client invoking it from a different domain. The particularity is that this cross-site invocation requires CORS (Cross-origin resource sharing), supported in IE8+ and other popular browsers.


The server (part 1)

To create the server, I create in Visual Studio an empty web application. Then I add a Search.asmx web-service, adding the following method:

[WebMethod]

public string DateTimeNow(string Where)

{

return DateTime.Now.ToLongTimeString() + " in " + Where;

}

Then to test it I easily deploy it to the Azure Website http://corsserviceapplication.azurewebsites.net/.


The client

To create the client, I create in Visual Studio another empty web application. I add a reference to the jQuery NuGet package, then I add a simple html page and an App.js file.

Here the html page:

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>My CORS Client Page</title>

<script src="Scripts/jquery-2.1.4.js"></script>

<script src="Scripts/App.js"></script>

</head>

<body>

<input id="city" type="text" value="Basel" />

<input type="button" value="Press here" onclick="test_cors_client(false, document.getElementById('city').value);" />

</body>

</html>


The App.js file is copied here too:
function test_cors_client(simple, where)
{
function escapeHTML(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

var soapEnv, soapAction;
if (simple) {
soapEnv =
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> \
<soap:Body> \
<HelloWorldResponse xmlns=\"http://tempuri.org/\"> \
<HelloWorldResult>string</HelloWorldResult> \
</HelloWorldResponse> \
</soap:Body> \
</soap:Envelope>";
soapAction = "http://tempuri.org/HelloWorld";
}
else {
soapEnv =
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> \
<soap:Body> \
<DateTimeNow xmlns=\"http://tempuri.org/\"> \
<Where>" + escapeHTML(where) + "</Where> \
</DateTimeNow> \
</soap:Body> \
</soap:Envelope>";
soapAction = "http://tempuri.org/DateTimeNow";
}

$.ajax({
//url: "http://localhost:8118/Search.asmx",
url: "http://corsserviceapplication.azurewebsites.net/Search.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\"",
headers: {
"SOAPAction": soapAction
}
});
function processResult(xData, status) {
if (status != "success") {
alert("error\n\n" + xData.responseText);
return;
}
alert("success\n\n" + xData.responseText);
}
/* var createCORSRequest = function (method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Most browsers.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// IE8 & IE9
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
};

//var url = "http://localhost:8118/Search.asmx";
var url = 'http://corsserviceapplication.azurewebsites.net/Search.asmx';
var method = 'POST';
var xhr = createCORSRequest(method, url);
xhr.setRequestHeader("Content-Type", "text/xml; charset=\"utf-8\"");

xhr.onload = function (e) {
// Success code goes here.
alert('success\n\n' + e.target.responseText);
};

xhr.onerror = function (e) {
// Error code goes here.
alert('error\n\n' + e.target);
};

xhr.setRequestHeader("SOAPAction", soapAction);
xhr.send(soapEnv);*/
}

This file contains both the jQuery implementation using $.ajax, and the XmlHttpRequest + XDomainRequest produced using test-cors.org.
Trying the example, you will see that it works when the example is run locally (with Service.asmx copied in the same client website), but not with CORS.

The server (part 2)

To enable CORS on the server, we need to add additional headers on the server, and one quick method is to modify the web.config as here below:

<?xml version="1.0" encoding="utf-8"?>

<!--

For more information on how to configure your ASP.NET application, please visit

http://go.microsoft.com/fwlink/?LinkId=169433

-->

<configuration>

<system.web>

<compilation debug="true" targetFramework="4.5" />

<httpRuntime targetFramework="4.5" />

</system.web>


<system.webServer>

<httpProtocol>

<customHeaders>

<add name="Access-Control-Allow-Origin" value="*" />

<add name="Access-Control-Allow-Headers" value="Content-Type, SOAPAction" />

</customHeaders>

</httpProtocol>

</system.webServer>

</configuration>


Now it will be possible to invoke the Search.asmx web-service even from another domain through CORS and here is the zip file containing the complete solution: CORS_Test.zip (704.8KB).


A few links used for reference:

C#: background task in a WinForm application containing a long running task

Recently I had to develop a WinForm application doing some checks. During development, with test data, everything was fast and the UI was acceptable. But once running the application with real data, as it was much more, I understood I was facing a long running task, as the UI was not responsive for 2+ hours.

From my studies, I knew the solution was to use the BackgroundWorker component, and one example was in How to: Run an Operation in the Background.

This was fine in the "old" versions of .NET, and even if still supported, I did some researches to see if a more modern approach was available, for example using the Task class introduced in .NET 4.
In fact the solution is pretty easy: you can run your background task with:

Task t = Task.Factory.StartNew(() =>
{
// do your long-time processing here
});
t.ContinueWith((Success) =>
{
// callback when task is complete
}, TaskContinuationOptions.NotOnFaulted);
t.ContinueWith((Fail) =>
{
// callback when task throws an exception
}, TaskContinuationOptions.OnlyOnFaulted);

And in how run now operations in the Task synced with the main thread, necessary to update the UI?
Using the Invoke method, better if after checking with the InvokeRequired property, as shown in C# - ThreadPool and Windows Forms.

.NET client side debugging and profiling with Glimpse

Glimpse is a client side library for debugging and profiling, that you can install in your Visual Studio project with NuGet.

It is fully described in the following blog posts:

 

There are also extension to Entity Framework, to track database requests, and Elmah, already discussed in my other article .NET Health Monitoring with Elmah, that allows to add recorded exceptions in a new tab.

 

Finally, it's possible to develop custom tabs, described in this serie of articles:

.NET Health Monitoring with Elmah

Elmah (Error Logging Modules and Handlers for ASP.NET) is a Google library that you can find at its dedicated web site: Elmah - Error Logging Modules and Handlers for ASP.NET.

This library is used for Health Monitoring and allows to trace unhandled exceptions, logging them and, optionally, viewing them in a dedicated page.

 

This library is that it is implemented with a custom HttpModule, as described in the article Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components.

In this way, the installation doesn't require any code recompilation, as it is enough to add copy DLLs to the bin folder and add some web.config entries.

 

Finally, the last article ELMAH (Error Logging Modules and Handlers) with SQL Server Compact explains how to install and configure ELMAH with the Local SQL.

async and await keywords in C# 5

The new version of the C# language, the version 5, introduces native support to async programming.

Async programming has always been available since the first version of .NET and C#, but now the development is really simplified, because the compiler is taking care of all the burden to deal with it.

To understand this semplification, and explain the support that the compiler is giving to the developer, we can summarize in the following points:

  • when you need to execute a lenghty operation, use the await keyword;
  • mark methods with await keywords with the async keyword;
  • logically, what the compiler will do is:
    1. generate the first part of the method up to the async call;
    2. the async call will be done passing as callback another "hidden" method,
    3. that will be defined with the remaining of the body content, and will be able to consume the output of the async call;
  • pratically, this construction makes use of the Task<T> class, where T is the type of the output of the async call;
  • one final note: in a async method, multiple await are possible.

As reference, there are the following articles: