Category Archives: WCF

WCF Callback function – FileSystemWatcher

FileSystemWatcher class allows to get notification on any change in the directory. The notification can be even filtered by changes like rename, delete and all. File types can be specified to the class to allow notification for a particular file types.

Code Snippet
  1. Dim watchFile As New FileSystemWatcher()
  2.         watchFile.Filter = ConfigurationManager.AppSettings.Item(“FileType”)
  3.         watchFile.IncludeSubdirectories = False
  4.         watchFile.Path = ConfigurationManager.AppSettings.Item(“WatcherPath”)
  5.         AddHandler watchFile.Changed, AddressOf FileNotification
  6.         AddHandler watchFile.Renamed, AddressOf FileNotification
  7.         AddHandler watchFile.Deleted, AddressOf FileNotification
  8.         watchFile.EnableRaisingEvents = True

The file watcher is implemented using the WCF Callback function. Whenever any change in the specified directory an event is triggered and a callback function is called. The WCF client program will listen to the callback function and update the control. For sample program the changes are formed as XML string and returned in the callback. When the callback function is called the xml is updated to the rich text control of the forms client.

Code Snippet
  1. Public Class NotificationImpl
  2.     Implements CallbackClient.ServiceClient.ICallbackServiceCallback
  3.     Private rtx As RichTextBox
  4.     Public Sub New(ByVal MyRtx As RichTextBox)
  5.         rtx = MyRtx
  6.     End Sub
  7.     Public Sub Callback(ByVal OutXml As String) Implements ServiceClient.ICallbackServiceCallback.Callback
  8.         rtx.AppendText(“——-START: “ & DateTime.Now.ToString(“dd/MMM/yyyy hh:mm:ss”) & “———-“ & Chr(13))
  9.         rtx.AppendText(OutXml)
  10.         rtx.AppendText(Chr(13) & “————-END ————–“ & Chr(13))
  11.     End Sub
  12. End Class

The WCF service is implemented using the NetTcp binding. The attached file contains the WCF service library and the Console Host for the service. The second attachment contains the form client to get the notification. The samples are in VB code

Download the Source code from below links…

Callback Service Code

Callback Client

WCF Service Error Hosting – Adding reference to netTcp binding service error

 

System.InvalidOperationException: Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].
   at System.ServiceModel.ServiceHostBase.MakeAbsoluteUri(Uri relativeOrAbsoluteUri, Binding binding, UriSchemeKeyedCollection baseAddresses)

image

Metadata contains a reference that cannot be resolved: ‘net.tcp://localhost:8732/Callback.ServiceLibrary/CallbackService/’.
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was ’00:05:00′.
An existing connection was forcibly closed by the remote host
If the service is defined in the current solution, try building the solution and adding the service reference again.

Resolution:

step 1: Adding the mex metadata to the config solved the issue

Add the below endpoint to the service node

<endpoint address="mex"
                 binding="mexTcpBinding"
                 contract="IMetadataExchange"/>

step 2: Add the Service metadata tag to the service behaviors node

<serviceBehaviors>
        <behavior name="Callback.ServiceLibrary.CallbackServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="False" />
          <serviceMetadata policyVersion="Policy15"/>
        </behavior>
      </serviceBehaviors>

step 3: Use the url net.Tcp://localhost:8732/mex to add the service reference not the full url

 

Serialize the Data to XML

public static String SerializeInterface(object SerializedObject)
       {
           using (MemoryStream stream = new MemoryStream())
           {
               XmlSerializer serializer = null;
               if (SerializedObject.GetType() == typeof(INTERFACE_ERRORS))
               {
                   serializer = new XmlSerializer(typeof(INTERFACE_ERRORS));
                   INTERFACE_ERRORS o = (INTERFACE_ERRORS)SerializedObject;
                   serializer.Serialize((Stream)stream, o);
               }
               else if (SerializedObject.GetType() == typeof(DETAILS_TO_SUB_SYSTEM))
               {
                   serializer = new XmlSerializer(typeof(DETAILS_TO_SUB_SYSTEM));
                   DETAILS_TO_SUB_SYSTEM details_to_sub_system = (DETAILS_TO_SUB_SYSTEM)SerializedObject;
                   serializer.Serialize((Stream)stream, details_to_sub_system);
               }

               stream.Seek(0L, SeekOrigin.Begin);
               byte[] buffer = new byte[stream.Length];
               int count = stream.Read(buffer, 0, 20);
               while (count < stream.Length)
               {
                   buffer[count++] = Convert.ToByte(stream.ReadByte());
               }

               char[] chars = new char[Encoding.UTF8.GetCharCount(buffer, 0, count)];
               Encoding.UTF8.GetDecoder().GetChars(buffer, 0, count, chars, 0);
               return new string(chars);
           }
       }

WCF Service – A name was started with an invalid character. Error processing resource

Error Details:

The XML page cannot be displayed

Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.


A name was started with an invalid character. Error processing resource

http://SENWIN2008/WCF/Service/’

<%@ ServiceHost Language="C#" Debug="true" Service="Service Name" CodeBehind="Service.svc.cs" %>

Resolution

  1. Check whether the IIS site is configured for .NET 2.0, in the ASP.NET tab of the properties, in some cases the ASP.NET will be 1.1 reference.
  2. If the above is not solved, may be the order of installation of .NET is wrong. Always need to install IIS and then .NET 3.5. If thats the case run the ServiceModelReg.exe from the framework folder this should solve the issue.

Class to Validate XML Against XSD

Recently i was involved in programming generic interface for Submitting PO. I came across the XSD concept of programming. I used the XSD to validate xml passed from different sub system and serialize the data.

Below is the sample code to validate the Xml against Xsd

/////////////////////////////

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Schema;
using System.Xml;
using System.IO;

namespace XSDValidation
{
    public static class POXsdValidation
    {
        private static string ErrorMessage;

public enum XmlType
    {
        XSD1,
        XSD2
    }

        public static string XsdError
        {
            get
            {
                return ErrorMessage;
            }
        }
        /// <summary>
        /// Validates the xml string against the xsd
        /// </summary>
        /// <param name="InputXml">Xml String contains the full xml</param>
        /// <param name="XsdPath">Xsd Path to be validated</param>
        private static void ValidateXmlByPath(string InputXml,string XsdPath)
        {
            StringReader xmlString = new StringReader(InputXml);
            ////StringReader xsdReader = new StringReader(XsdPath);
            ErrorMessage = string.Empty;
            ////XmlReader XsdReader = XmlReader.Create(xsdReader);

            //// Create the XmlSchemaSet class.
            XmlSchemaSet sc = new XmlSchemaSet();

            //// Add the schema to the collection.
            sc.Add(null, XsdPath);

            //// Set the validation settings.
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.Schema;
            settings.Schemas = sc;
            settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

            //// Create the XmlReader object.
            XmlReader reader = XmlReader.Create(xmlString, settings);

            //// Parse the file.
            while (reader.Read())
            {
            }
        }
        /// <summary>
        /// Validates the xmlreader content against xsd
        /// </summary>
        /// <param name="InputXml">Xml Reader</param>
        /// <param name="XsdPath">XSD Path</param>
        private static void ValidateXml(XmlReader InputXml, string XsdPath)
        {
            ////StringReader xmlString = new StringReader(InputXml);
            ////StringReader xsdReader = new StringReader(XsdPath);
            ErrorMessage = string.Empty;
            ////XmlReader XsdReader = XmlReader.Create(xsdReader);

            //// Create the XmlSchemaSet class.
            XmlSchemaSet sc = new XmlSchemaSet();

            //// Add the schema to the collection.
            sc.Add(null, XsdPath);

            //// Set the validation settings.
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.Schema;
            settings.Schemas = sc;
            settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

            //// Create the XmlReader object.
            XmlReader reader = XmlReader.Create(InputXml, settings);

            //// Parse the file.
            while (reader.Read())
            {
            }
        }
        /// <summary>
        /// Validates the Xml Against xsd
        /// </summary>
        /// <param name="InputXml">Input Xml String to Validate</param>
        /// <param name="InputType">Type of Validation</param>
        public static void ValidateXml(string InputXml,XmlType InputType)
        {
            string PathWCF = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
            //// Add the schema to the collection.
            switch (InputType)
            {
                case XML1:
                    PathWCF += "\\bin\\schemas\\XSD1.xsd";
                    break;
                case XML2:
                    PathWCF += "\\bin\\schemas\\XSD2.xsd";
                    break;
            }

            ValidateXmlByPath(InputXml, PathWCF);
        }
        /// <summary>
        /// Callback function for Validate Schema
        /// </summary>
        /// <param name="sender">Object value</param>
        /// <param name="e">Validation message object</param>
        private static void ValidationCallBack(object sender, ValidationEventArgs e)
        {
            ErrorMessage += "<Validation>" +  e.Message + "</Validation>" ;
        }
    }
}

WCF DataService with Custom Function and parameter

namespace Senthamil.Sample

{
    public class PORSS : DataService<ModelEntities>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            config.SetEntitySetAccessRule(“RSS_STATUS”, EntitySetRights.AllRead);
            config.SetServiceOperationAccessRule(“MyFunction”, ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }

        [WebGet]
        public IQueryable<RSS_STATUS> MyFunction(string RefNumb)
        {
            ModelEntities MySource = new ModelEntities();
            return from c in MySource.RSS_STATUS
                   where c.SUB_SYSTEM_NUMBER == RefNumb
                   select c;
        }
    }
}

WCF Resources

Now after finishing with my mobile app for MOSS 2007, i have started writing a WCF service for SharePoint 2007. I found that the WebServices found in the SharePoint Server is not sufficient to do all the tasks which i want to perform through mobile. So i decided to create my own WCF service to accomplish those. Moreover i can use the WCF service to communicate to Silverlight in the future for SharePoint.

To start with any new tech MSDN is always the best place. So i started to read an article about WCF to the link below

http://msdn.microsoft.com/en-us/library/ms735119.aspx

Once i finished reading and try out with some basic WCF and sample from MSDN i started hunting for tutorial videos. I found the below links have good WCF videos. Microsoft has 15 part webcast for WCF which is the best way to learn WCF. I always download videos to my laptop and convert it to my PSP to watch when i am in train or traveling in the bus. Its a better way to learn and kill time usefully.

Below are the links for the WCF videos

 

The Both the link 1 and 2 are same points to the msevents

Link 1 http://www.dasblonde.net/2007/06/24/WCFWebcastSeries.aspx 

Link 2 http://idealprogrammer.com/languages/visual-basic-vbnet/windows-communication-foundation-15-hours-of-free-video-tutorials/

Channel 9 WCF (mix of all videos need to filter)

Link3 http://channel9.msdn.com/tags/WCF/#Page=3

WCF Security

Link 4 http://www.codeplex.com/wikipage?ProjectName=WCFSecurity&title=How%20Tos

Link 5 http://www.codeplex.com/wikipage?ProjectName=WCFSecurity&title=Video%20Index

Basic WCF (Need subscription)

Link 6 http://www.pluralsight.com/main/olt/Course.aspx?n=wcf-fundamentals