Tuesday, November 29, 2011

How to cancel a Parallel.For or Parallel.ForEach loop

We can cancel the Parallel.For or Parallel.ForEach using a CancellationToken as shown below:

namespace CancelParallelLoops
{
    using System;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    class Program
    {
        public static void Main()
        {
            int[] nums = Enumerable.Range(0, 10000000).ToArray();
            CancellationTokenSource cts = new CancellationTokenSource();
 
           // Use ParallelOptions instance to store the CancellationToken
            ParallelOptions po = new ParallelOptions();
            po.CancellationToken = cts.Token;
            po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
 
            Console.WriteLine("Press any key to start. Press 'c' to cancel.");
            Console.ReadKey();            
 
            // Run a task so that we can cancel from another thread.
            Task.Factory.StartNew(() =>
            {
                if (Console.ReadKey().KeyChar == 'c')
                    cts.Cancel();
 
                Console.WriteLine("press any key to exit");
            });
 
            try
            {
                Parallel.ForEach(nums, po, (num) =>
                {
                    double d = Math.Sqrt(num);
                    Console.WriteLine("{0} on {1}", d, Thread.CurrentThread.ManagedThreadId);
                    po.CancellationToken.ThrowIfCancellationRequested();
                });
            }
            catch (OperationCanceledException e)
            {
                Console.WriteLine(e.Message);
            }
 
            Console.ReadKey();
        }
    }
}

How to use DataBinding with DataServiceCollections?

The following link explains on how to perform data binding with DataServiceCollections.

Data Binding with DataServiceCollections

Tuesday, November 22, 2011

Xml Viewer in WinForms application

We can create a XmlViewer using a WPF user control and use it in our windows forms application.

Create a new class library project and add a WPF user control called XmlViewer


<UserControl x:Class="Viewer.XmlViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:xmlstack="clr-namespace:System.Xml;assembly=System.Xml"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.Resources>
        <SolidColorBrush Color="Blue" x:Key="xmlValueBrush"/>
        <SolidColorBrush Color="Red" x:Key="xmAttributeBrush"/>
        <SolidColorBrush Color="DarkMagenta" x:Key="xmlTagBrush"/>
        <SolidColorBrush Color="Blue" x:Key="xmlMarkBrush"/>
        <DataTemplate x:Key="attributeTemplate">
            <StackPanel Orientation="Horizontal"                        Margin="3,0,0,0" HorizontalAlignment="Center">
                <TextBlock Text="{Binding Path=Name}" 
                           Foreground="{StaticResource xmAttributeBrush}"/>
                <TextBlock Text="=&quot;" 
                           Foreground="{StaticResource xmlMarkBrush}"/>
                <TextBlock Text="{Binding Path=Value}" 
                           Foreground="{StaticResource xmlValueBrush}"/>
                <TextBlock Text="&quot;" 
                           Foreground="{StaticResource xmlMarkBrush}"/>
            </StackPanel>
        </DataTemplate>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="True"/>
        </Style>
        <HierarchicalDataTemplate x:Key="treeViewTemplate" 
                                  ItemsSource="{Binding XPath=child::node()}">
            <StackPanel Orientation="Horizontal" Margin="3,0,0,0" 
                        HorizontalAlignment="Center">
                <TextBlock Text="&lt;" HorizontalAlignment="Center" 
                           Foreground="{StaticResource xmlMarkBrush}" 
                           x:Name="startTag"/>
                <TextBlock Text="{Binding Path=Name}"
                    Margin="0"
                    HorizontalAlignment="Center"
                    x:Name="xmlTag"
                    Foreground="{StaticResource xmlTagBrush}"/>
                <ItemsControl
                    ItemTemplate="{StaticResource attributeTemplate}"
                    ItemsSource="{Binding Path=Attributes}"
                    HorizontalAlignment="Center">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
                <TextBlock Text="&gt;" HorizontalAlignment="Center" 
                           Foreground="{StaticResource xmlMarkBrush}" 
                           x:Name="endTag"/>
            </StackPanel>
            <HierarchicalDataTemplate.Triggers>
                <DataTrigger Binding="{Binding NodeType}">
                    <DataTrigger.Value>
                        <xmlstack:XmlNodeType>Text</xmlstack:XmlNodeType>
                    </DataTrigger.Value>
                    <Setter Property="Text" Value="{Binding InnerText}" 
                            TargetName="xmlTag"/>
                    <Setter Property="Foreground" Value="Blue" 
                            TargetName="xmlTag"/>
                    <Setter Property="Visibility" Value="Collapsed" 
                            TargetName="startTag"/>
                    <Setter Property="Visibility" Value="Collapsed" 
                            TargetName="endTag"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding HasChildNodes}" Value="False">
                    <Setter Property="Text" Value="/&gt;" TargetName="endTag"/>
                </DataTrigger>
            </HierarchicalDataTemplate.Triggers>
        </HierarchicalDataTemplate>
    </UserControl.Resources>
    <Grid>
        <TreeView Grid.Row="2" Grid.ColumnSpan="2" Name="xmlTree" 
                  ItemTemplate="{StaticResource treeViewTemplate}"/>
    </Grid>
</UserControl>

The code behind for the above user control as shown below:


public partial class XmlViewer : UserControl
{
    private XmlDocument xmldocument;
    public XmlViewer()
    {
        InitializeComponent();
    }
 
    public XmlDocument XmlDocument
    {
        get { return xmldocument; }
        set
        {
            xmldocument = value;
            BindXmlDocument();
        }
    }
 
    private void BindXmlDocument()
    {
        if (xmldocument == null)
        {
            xmlTree.ItemsSource = null;
            return;
        }
 
        var provider = new XmlDataProvider {Document = xmldocument};
        var binding = new Binding {Source = provider, XPath = "child::node()"};
        xmlTree.SetBinding(ItemsControl.ItemsSourceProperty, binding);
    }
}

Once you are done with the above things now build the project. Now create a new Windows Forms project and add a reference of this Dll. Now open a form and add a WPF Interoperability control called ElementHost. Once you add this then you can see in the select hosted content dropdown the XmlViewer control. If you dont find it just try building your project once and it should come up. Now in the code behind of your forms control do the following:

private void btnBrowse_Click(object sender, EventArgs e)
        {
                XmlDocument XMLdoc = new XmlDocument();
                try
                {
                    XMLdoc.Load(@"C:\Sample.xml");
                }
                catch (XmlException)
                {
                    MessageBox.Show("The XML file is invalid");
                    return;
                }
                ((XmlViewer) wpfElementHost.Child).XmlDocument = XMLdoc;
        }

How to implement a binary tree in C# using Generics

We can implement a binary tree in C# using generics as shown here.

Tuesday, November 15, 2011

Quick start with Moq framework

The below article gives a quick start with Moq framework to use when unit testing.

Moq - Quick start

Tuesday, November 8, 2011

Support for large URL's

We might encounter scenarios where the URL that we need to have is very large when developing applications. In such cases we need to do the below configurations in order to have large URL's:

In the web.config set the following:


<system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpRuntime  maxUrlLength="2048" maxQueryStringLength="2048" maxRequestLength="2048" />
  </system.web>

Then find the registry setting for a URLSegmentLength and increase it to some value appropriate:

UrlSegmentMaxLength registry setting, increasing to 2048 (x800)

If the service is being hosted in IIS then also add the following to the webServer section in web.config:

<system.webServer>
      <security>
         <requestFiltering>
            <requestLimits maxUrl="a large value"/>              
         </requestFiltering>
      </security>
   </system.webServer>
 

That should be enough for you to have your URL's to be very large.

Monday, November 7, 2011

What is IIS Express?

IIS Express is a lightweight, self-contained version of IIS optimized for developers. IIS Express makes it easy to use the most current version of IIS to develop and test websites. It has all the core capabilities of IIS 7 as well as additional features designed to ease website development including:
  • It doesn't run as a service or require administrator user rights to perform most tasks.
  • IIS Express works well with ASP.NET and PHP applications.
  • Multiple users of IIS Express can work independently on the same computer

For more information, click here.

Also on how to use IIS Express, click here.

Friday, November 4, 2011

WCF REST Exception handling

WCF REST Exception handling

.NET Client to invoke a REST Service

To access a REST Service you can use the below code:


using System.Net;
using System.IO;
 
public string UseHttpWebApproach<T>(string serviceUrl, string resourceUrl, string method, T requestBody)
{
    string responseMessage = null;
    var request = WebRequest.Create(string.Concat(serviceUrl, resourceUrl)) as HttpWebRequest;
    if (request != null)
    {
        request.ContentType = "text/xml";
        request.Method = method;
    }
 
    if(method == "POST" && requestBody != null)
    {
        // NOTE: The below can be used when you want to serialize the request using XmlSerializer
 
        //byte[] requestBodyBytes = ToByteArrayUsingXmlSer(requestBody, "http://schemas.datacontract.org/2004/07/XMLService");
 
        // NOTE: The below code is used as we are serializing the request using DataContractSerializer
 
        byte[] requestBodyBytes = ToByteArrayUsingDataContractSer(requestBody);
        request.ContentLength = requestBodyBytes.Length;
        using (Stream postStream = request.GetRequestStream())
            postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);
    }
 
    if (request != null)
    {
        var response = request.GetResponse() as HttpWebResponse;
        if(response.StatusCode == HttpStatusCode.OK)
        {
            Stream responseStream = response.GetResponseStream();
            if (responseStream != null)
            {
                var reader = new StreamReader(responseStream);
                responseMessage = reader.ReadToEnd();
            }
        }
        else
        {
            responseMessage = response.StatusDescription;
        }
    }
    return responseMessage;
}
 
private static byte[] ToByteArrayUsingDataContractSer<T>(T requestBody)
{
    byte[] bytes = null;
    var serializer1 = new DataContractSerializer(typeof(T));
    var ms1 = new MemoryStream();
    serializer1.WriteObject(ms1, requestBody);
    ms1.Position = 0;
    var reader = new StreamReader(ms1);
    bytes = ms1.ToArray();
    return bytes;
}
 
private static byte[] ToByteArrayUsingXmlSer<T>(T requestBody, string xmlNamespace)
{
    byte[] bytes; 
    using (var s = new MemoryStream())
    {
        var serializer = new XmlSerializer(typeof(T), xmlNamespace);
        serializer.Serialize(s, requestBody);
        bytes = s.ToArray();
    }
    return bytes;
}


Using 3rd party library such as RestSharp the client code is as shown below:


private string UseRestSharpApproach(string serviceBaseUrl, string resourceUrl, Method method, object requestBody)
{
    var client = new RestClient();
    client.BaseUrl = serviceBaseUrl;
    var request = new RestRequest(method) {DateFormat = DataFormat.Xml.ToString(), Resource = resourceUrl};
    request.AddParameter("text/xml", requestBody, ParameterType.RequestBody);
    //request.AddParameter("xmlString", HttpUtility.HtmlEncode(requestBody));
    var response = client.Execute(request);
    string responseString;
    if (response.StatusCode == HttpStatusCode.OK)
    {
        responseString = HttpUtility.HtmlDecode(response.Content);
    }
    else
    {
        responseString = response.StatusDescription + " --------------------" + HttpUtility.HtmlDecode(response.Content);
    }
    return responseString;
}

The possible values for parameters are :
  1. ServiceUrl : http://localhost/RestSample/RestService.svc
  2. ResourceUrl:
      • GetDataFromStringAsString
      • GetDataUsingDataContract
      • GetDataFromString
  3. Various types of RequestBody are shown below:


    • <?xml version=""1.0""?><product id='1'>
          <name>Bread</name>
          <price unit='un'>2.50</price>
      </product>

      CompositeType objComposite = new CompositeType();
      objComposite.BoolValue = true;
      objComposite.StringValue = "Hello World";

      <SampleItem xmlns="http://schemas.datacontract.org/2004/07/XMLService"  xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
          <Id>7</Id>
          <StringValue>Hello World</StringValue>
      </SampleItem>

One thing to note when using RestSharp library and you want to pass a simple string such as "Hello World" to the REST Service should be sent as shown below:


<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/"> Hello World</string>

The response from a REST Service is always mapped to a HTTP status codes such as 200, 400, 500, 404

For a list of status code and what they mean you can find them here.

If you want to know the exact error on what the error was you can enable tracing on your Services. You can do that as i explained in my previous blog here 

Building a REST Service using WCF

The below code gives a server implementation of building a REST Service using WCF.


[ServiceContract]
public interface IService1
{
[WebGet]
string GetData();    
 
[WebGet]
string GetDataFromValue(int value);    
 
[WebInvoke]
CompositeType GetDataUsingDataContract(SampleItem sample);
 
[WebInvoke]
XElement GetDataFromString(XElement xmlString);
 
[WebInvoke]
string GetDataFromStringAsString(string xmlString);        
}


public class SampleItem
{
    public int Id { get; set; }
    public string StringValue { get; set; }
    public Child MyChild { get; set; }
}
 
public class Child
{
    public string ChildInfo { get; set; }
}

 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[KnownType(typeof(CompositeType))]
public class Service1 : IService1
{
public string GetData()
{
return "Welcome to server";
}
 
public string GetDataFromValue(int value)
{
return string.Format("You entered: {0}", value);
}    
 
public SampleItem GetDataUsingDataContract(SampleItem sample)
{
if (sample == null)
{
throw new ArgumentNullException("sample");
}
if (sample.BoolValue)
{
sample.StringValue += "Suffix";
}
return sample;
}
 
public XElement GetDataFromString(XElement xmlString)
{
xmlString.Name = xmlString.Name + "_modified";
return xmlString;
}
 
public string GetDataFromStringAsString(string xmlString)
{
if (xmlString.Length > 0)
return "Hello World";
return "No String";
}
 
public string GetDataFromStrings()
{
string xmlString = HttpContext.Current.Request.Form["xmlString"];
string strXml = HttpContext.Current.Request.Form["strXml"];
if (xmlString.Length > 0 && strXml.Length > 0)
return xmlString + strXml + " appended from server";
return "Either of the string is empty";
}
}

The AspNetCompatiblity mode is set to access the HttpContext. in the GetDataFromStrings() method.

Also we can build the same Rest service in an MVC style as shown below:


[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class RestService
{
// TODO: Implement the collection resource that will contain the SampleItem instances
private static List<SampleItem> sampleCollection = new List<SampleItem>();
[WebGet]
public List<SampleItem> GetCollection()
{
// TODO: Replace the current implementation to return a collection of SampleItem instances
if (sampleCollection.Count == 0)
{
sampleCollection = new List<SampleItem>();
sampleCollection.Add(new SampleItem() { Id = 1, StringValue = "Hello 1" });
sampleCollection.Add(new SampleItem() { Id = 2, StringValue = "Hello 2" });
sampleCollection.Add(new SampleItem() { Id = 3, StringValue = "Hello 3" });
sampleCollection.Add(new SampleItem() { Id = 4, StringValue = "Hello 4" });
sampleCollection.Add(new SampleItem() { Id = 5, StringValue = "Hello 5" });
}
return sampleCollection;
}
 
[WebInvoke]
public SampleItem Create(SampleItem instance)
{   
sampleCollection.Add(instance);
return instance;
}
 
[WebGet(UriTemplate = "{id}")]
public SampleItem Get(string id)
 
{
// TODO: Return the instance of SampleItem with the given id
return sampleCollection.Where(i => i.Id == Convert.ToInt32(id)) as SampleItem;
}
 
[WebInvoke(UriTemplate = "{id}", Method = "PUT")]
public SampleItem Update(string id, SampleItem instance)
{
SampleItem objSample = sampleCollection.Where(i => i.Id == Convert.ToInt32(id)) as SampleItem;
objSample = instance;
return objSample;
}
 
[WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
public void Delete(string id)
{
sampleCollection.Remove(sampleCollection.Where(i => i.Id == Convert.ToInt32(id)) as SampleItem);
}
 
[WebInvoke]
public string InsertSampleItemFromXml(XElement xmlString)
{
if(!String.IsNullOrEmpty(xmlString.ToString()))
{
return "Got this xml on server -----> " + xmlString.ToString();
}
else
{
return "Excpetion";
}
}
}

You then have to register this in the Global.asax as shown below:


public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
 
private void RegisterRoutes()
{
// Edit the base address of Service1 by replacing the "Service1" string below
RouteTable.Routes.Add(new ServiceRoute("RestService", new WebServiceHostFactory(), typeof(RestService)));
}
}

Once you do this you would have the URL for the service as shown when hosted in IIS:


http://localhost/RestVirtualDirectory/RestService/Create or
http://localhost/RestVirtualDirectory/RestService/GetCollection or
http://localhost/RestVirtualDirectory/RestService/Update

Thursday, November 3, 2011

How to enable Tracing in WCF

To enable tracing on a WCF Service place the below xml in the web.config file under <configuration> section.

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="All" propagateActivity="true">
        <listeners>
          <add type="System.Diagnostics.DefaultTraceListener" name="Default">
            <filter type="" />
          </add>
          <add name="xml">
            <filter type="" />
          </add>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging" switchValue="All">
        <listeners>
          <add type="System.Diagnostics.DefaultTraceListener" name="Default">
            <filter type="" />
          </add>
          <add name="xml">
            <filter type="" />
          </add>
        </listeners>
      </source>
      <source name="XMLService.dll" switchValue="Warning, ActivityTracing">
        <listeners>
          <add type="System.Diagnostics.DefaultTraceListener" name="Default">
            <filter type="" />
          </add>
          <add name="xml">
            <filter type="" />
          </add>
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add initializeData="C:\WCFServiceTrace.svclog"
        type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        name="xml" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
        <filter type="" />
      </add>
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>

You can find more information on Tracing here

What is New in WCF 4.0?

To know what is new in WCF 4 go through this link