Monday, July 15, 2013

Progress of a Task in C#

By default Task doesn’t report it’s progress as a BackgroundWorker does. But that doesn’t mean we can’t get a progress of a Task. There is a new interface which was introduced with .NET framework 4.5 which is IProgress<T>. This interface exposes a Report(T) method, which the async task calls to report progress.

Let’s go by an example. I have the following async method.
async Task MyMethodAsync(int sleepTime, IProgress<MyTaskProgressReport> progress)
{
    int totalAmount = 10000; 

    for (int i = 0; i <= totalAmount;)
    {
        await Task.Delay(sleepTime);
        progress.Report(new MyTaskProgressReport { CurrentProgressAmount = i, TotalProgressAmount = totalAmount, CurrentProgressMessage = string.Format("On {0} Message", i) });
        i = i + sleepTime;
    }
}
It takes a progress parameter which is a IProgress of type “MyTaskProgressReport” and here is my “MyTaskProgressReport” class.
public class MyTaskProgressReport
{
   //current progress
   public int CurrentProgressAmount { get; set; }
   //total progress
   public int TotalProgressAmount { get; set; }
   //some message to pass to the UI of current progress
   public string CurrentProgressMessage { get; set; }
}
To simulate a time taking task, inside my async method, I have a For loop and inside it I have a Task Delay. In every iteration, progress is reported to the caller. Now let’ see how UI captures this.

On the UI thread, we have to define an event handler Action<T>, which will be called when IProgress<T>.Report is invoked.
private void ReportProgress(MyTaskProgressReport progress)
{
    label1.Text = progress.CurrentProgressMessage;
    textBox1.Text = string.Format("{0} out of {1}", progress.CurrentProgressAmount, progress.TotalProgressAmount);
}
Now I am going to call my async method. I have created a Progress<T> instance and invoked the async method, which is triggered by a button click.
private async void button1_Click(object sender, EventArgs e)
{
    var progressIndicator = new Progress<MyTaskProgressReport>(ReportProgress);
    await MyMethodAsync(1000, progressIndicator);
}
Here is the output,
image
Result
I have uploaded a full sample to my SkyDrive. Do check it out.


Happy Coding.

Regards
Jaliya

Thursday, July 11, 2013

Set WCF Service Authentication to Use a Custom Username & Password over HTTP

It’s a common requirement where you want to authenticate the requests which the clients will make to your WCF services. And let's say that’s using with some data which you have in your user table. In WCF, the default when a user name and password is used for authentication is let Windows to validate the user name and password using Windows Authentication. But if you want to authenticate users with custom validation, of course that’s possible with WCF, because of this custom validation scheme which is known as Validators. You will just have to create a class which will inherit from UserNamePasswordValidator class(which is provided with the .NET framework itself).

Now let’s see this in action. I have created a WCF application and I will just keep the default classes as it is. Now I am going to add a new class which is ServiceAuthenticator and going to inherit from UserNamePasswordValidator. For that I need to add reference to System.IdentityModel.

ServiceAuthenticator.cs
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens; 

namespace WcfService1
{
    public class ServiceAuthenticator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (null == userName || null == password)
            {
                throw new ArgumentNullException();
            }

            if (!(userName == "username" && password == "password"))
            {
                throw new SecurityTokenException("Unknown Username or Password");
            }
        }
    }
}

Now I need to configure a binding which supports message security over any transport or transport-level security over HTTP(S). Since I assume all my services are accessed via HTTP, the options I can use is wsHttpBinding or CustomBinding. So I am moving forward with wsHttpBinding and modifying the web.config file to configure custom wsHttpBinding as follows.
<bindings>
  <wsHttpBinding>
    <binding name="MyBinding">
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

When that's done I am configuring a behavior which specifies that a custom user name and password validator is used for authentication. And now comes another important thing to the picture which is a Certificate. In Message security, the message is encrypted by a service certificate which we are going to configure in web.config. So for that let’s create a certificate first. There is handy tool which you can download from my SkyDrive, which is known as Pluralsight self-cert Tool. This is provided by Pluralsight to create and install certificates.

So let’s see how we can use this great tool to create a new certificate and install it.

image
Pluralsight self-cert
Make sure to run this tool As Administrator and I have given a name which is “MyCertficate”. I am saving the certificate inside LocalMachine and the store name is “My”. Once you clicked the save button it will show the following message.

image
Certificate is created and stored.
Now let’s make sure the certificate is successfully created and installed. Go to Run and type mmc.

image
MMC
File Add/Remove Snap-in.

image
Add/Remove Snap-in
Click on Certificates and Add.

image
Add Certificate
Computer Account.

image
Computer Account
Local Computer and Finish.

image
Local Computer
Now in mmc, navigate to Certificates->Personal->Certificates. There you can see the certificate I have just created using self-cert.

image
View Certificate
Now let’s move back to web.config file and start creating a behavior configuration with the service certificate.
<behaviors>
   <serviceBehaviors>
     <behavior name="MyBehavior">
       <serviceMetadata httpGetEnabled="true" />
       <serviceDebug includeExceptionDetailInFaults="true" />
       
       <serviceCredentials>
         <userNameAuthentication userNamePasswordValidationMode="Custom"
          customUserNamePasswordValidatorType="WcfService1.ServiceAuthenticator, WcfService1" /> 

         <serviceCertificate
           findValue="MyCertificate"
           x509FindType="FindBySubjectName"
           storeLocation="LocalMachine"
           storeName="My" />         

       </serviceCredentials>

     </behavior>
   </serviceBehaviors>
 </behaviors>

As you can see I have mentioned the userNamePasswordValidationMode as “Custom” and mentioned the ServiceCertificate.

Now let’s create the endpoints.
<services>
  <service behaviorConfiguration="MyBehavior" name="WcfService1.Service1">
    <endpoint address="Service1.svc" binding="wsHttpBinding"
              bindingConfiguration="MyBinding"
              contract="WcfService1.IService1" />

    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:34435" />
      </baseAddresses>
    </host>
  </service>
</services>

Please note that I have mentioned the created custom configurations in the service behavior configuration and endpoint binding configuration.

Now that’s almost done. Please make sure you can view your service in the browser. If you are hosting your service application in IIS, you will be thrown out with this error which is “Keyset does not exist”.

image
Keyset does not exist.

Download winhttpcertcfg.exe from here. After installing the tool, run the following command on the command prompt as Administrator. Go to directory where you have installed this tool. Default is, ”C:\Program Files (x86)\Windows Resource Kits\Tools”. From sitting inside that directory run the following command.

If your service applications’ application pool is DefaultAppPool,
winhttpcertcfg -g -c LOCAL_MACHINE\My -s MyCertificate -a DefaultAppPool
If it’s another application pool you have created in which the identity is let's say “NetworkService”, then the command should be follows.
winhttpcertcfg -g -c LOCAL_MACHINE\My -s MyCertificate -a networkservice
Once you run the command, you will see a message like this.

image
command
Now make sure you can view your service in the browser.

Then let’s move to the final part which is the client app. I have created a console application and added a service reference. And following is my code.
using System;
using ConsoleApplication1.ServiceReference1;
using System.ServiceModel.Security; 

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Service1Client c = new Service1Client();
                c.ClientCredentials.UserName.UserName = "username";
                c.ClientCredentials.UserName.Password = "password";
                c.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
                Console.WriteLine(c.GetData(5));
            }
            catch (MessageSecurityException ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
    }
}
As long I  can pass a valid username and a valid password to my ServiceAuthenticator class, I can consume the service. If not I will be thrown out with a error.

Success
Error
I am uploading a full sample to my SkyDrive.



Happy Coding.

Regards,
Jaliya

Tuesday, July 9, 2013

Document Library Capability in Modern Apps for Windows 8.1 Preview

If you examined the Package.appxmanifest for Windows 8.1 Preview app created using Visual Studio 2013 Preview, you will see some differences compared to a Package.appxmanifest for Windows 8 app created using Visual Studio 2012. If you have a closer look at the Capabilities tab, you can see that Document Library capability has been removed from the Package.appxmanifest for Windows 8.1 Preview app.
Package.appxmanifest2013
Windows 8.1 Preview on Visual Studio 2013 Preview
Package.appxmanifest2012
Windows 8 on Visual Studio 2012
Well I was wondering why it is removed and started looking for answers. I read this article on App capability declarations (Windows Store apps) and first let’s see what this app capability declarations are really there for.

There can be scenarios where the Windows Store apps that need programmatic access to users’ resources such as the Pictures library or connected devices such as a webcam etc. So to access such resources, appropriate capability should be declared in the apps’ Package.appxmanifest. When end users downloads the app from the Windows Store, they are notified of all the capabilities that the app declares. So end users know what resources will be accessed through out the app.

When we are talking about app capabilities, all the capabilities are categorized into following three types,
  • General use capabilities
  • Device capabilities
  • Special use capabilities
You can find more about these from here. Since we are are focusing on Document Library capability here, let’s focus more on the topic.

Document Library capability comes under Special use capabilities. Apps that apply the special use capabilities require a company account to submit them to the Windows Store and not from a individual account. The Document Library capability is highly restricted and not intended for general use, and apps which try to use it generally will fail certification (This is both for Windows 8 and Windows 8.1 Preview). So to avoid unwanted use of Document Library capability, I think Microsoft has dropped it from the appxmanifest.

However, this capability is gone just from the UI, you still can open appxmanifest as a source file and manually add the capability. And of course, that is not going to decrease the risk of failing your app in app certification process.

So in simple what Microsoft says is “We strongly recommend you avoid using this capability”.

For more information on this, please refer following links.

Thursday, July 4, 2013

Tasks Window in Visual Studio 2013 Preview

The Tasks Window is one of the nicest things which was introduced with Visual Studio 2013 Preview. This window will be very useful when debugging asynchronous code.

In Visual Studio 2010 and Visual Studio 2012 there is a windows called Parallel Tasks. You can view the  Parallel Tasks window either by typing Parallel Tasks in Quick Launch or by going to Debug -> Windows -> Tasks when you are debugging the code. This window is renamed to Tasks in Visual Studio 2013 Preview.

ParallelTasksWindow
Parallel Tasks Window
In addition to the functionality that Parallel Window offers in Visual Studio 2010 and 2012 in C# and VB, the Tasks window will show all of the tasks that are currently running or are scheduled to run in a asynchronous operation. Right now you might be wondering whether this Tasks window is supported only in C# and VB projects. Don't worry, this is supported for all the languages that are supported in Visual Studio for developing Windows Store applications.

You can access Task window in Visual Studio 2013 Preview by typing Tasks in Quick Launch or by going to Debug -> Windows -> Tasks and again that's when you are debugging the code. That's same as in Visual Studio 2010 and 2012.

Let’s take a look at the following code snippet.
private async void Button_Click(object sender, RoutedEventArgs e)
{
    await DoWork(http://www.microsoft.com);
} 

private async Task DoWork(string url)
{
    await Task.Yield();
    await GetString(url);
} 

private async Task GetString(string url)
{
    await Task.Yield();
    HttpClient httpClient = new HttpClient();
    string s = await httpClient.GetStringAsync(url);
}

Here I have a button and in it’s click event I am calling DoWork method asynchronously and from DoWork I am calling GetString method asynchronously. Here the awaited Task.Yield() is used to leave the current async code and to return back to the current context.

Now let’s put some breakpoints in the code. I have put two breakpoints in DoWork method and in GetString method. Now this is what you will see in the Tasks window.

OnDoWork
No Tasks in Tasks Window
There are no tasks created yet and let’s keep debugging. The moment control leaves the Task.Yield() in DoWork method, two tasks are created.

OnAwaitGetString
Tasks Window on await GetString
The task which the button click event is awaiting on is active. The task which is bound to Button click is scheduled to run. Again let’s keep debugging.

When the control comes to the line after Task.Yield() in GetString method this is what you will see in Tasks window.

OnHttpClient
Tasks Window after leaving Task.Yield in GetString
Now another task is created. Two tasks are active, the task which the Button click event is awaiting on and the task which the DoWork method is awaiting on. Still the task which is bound to Button click is scheduled to run.

And finally when you keep debugging and when the control leaves the line where the Button click calls the DoWork method, you can see that the task which is bound to Button click is now active.

OnLeavingDoWork
Tasks Window on leaving DoWork
And that’s about the Tasks window. As always love your feedback.

Happy Coding.

Regards,
Jaliya