TFS 2010 WorkItemChangedEvent subscription to receive SOAP messages using WCF .Net 4.0



TFS 2010 is extensible and exposes and API using which I was interested in receiving SOAP messages whenever any WorkItem changes in a certain collection on my TFS Server.

I wrote a WCF service, that will receive a SOAP message every time a WorkItem is changed in a designated collection on my TFS Server. I will upload the code soon.
Here's what the contract looks like:
using System.ServiceModel;
using Microsoft.TeamFoundation.Framework.Client;

namespace Smt.TfsEventListener
{
    [ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
    public interface IWorkItemSubscriber
    {
        [OperationContract(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify")]
        void Notify(string eventXml);
    }
}
 Here's what I do to dump the response on my local hard disk, once you get the XML, the possibilities are endless for what you want to do with that information, you can generate reports, send out emails, update your CRM systems etc.




using System;
using System.IO;

namespace Smt.TfsEventListener
{
    public class WorkItemSubscriber : IWorkItemSubscriber
    {
        public void Notify(string eventXml)
        {
            TextFileWriter obj = new TextFileWriter();
            obj.Write(eventXml);
        }
    }

    public class TextFileWriter
    {
        TextWriter tw;
        public void Write(string value)
        {
            try
            {
                string fileToWrite = @"E:\Response" + "_" + DateTime.Now.Minute.ToString() + "_" + DateTime.Now.Millisecond.ToString() + ".xml";
                tw = new StreamWriter(fileToWrite);
                tw.Write(value);
                tw.Close();
            }
            catch (Exception)
            { }
            finally {
                tw.Close();
            }
        }
    }
}
Here's what the config file looks like, please make sure, you follow the exact binding and endpoint settings:
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="noSecurity">
          <security mode="None"/>
        </binding>
      </wsHttpBinding >
    </bindings>
    <services>
      <service name="Smt.TfsEventListener.WorkItemSubscriber">
        <endpoint address="basic" binding="wsHttpBinding" bindingConfiguration="noSecurity"
          name="wsHttpBinding" contract="Smt.TfsEventListener.IWorkItemSubscriber" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>
You need to run the following line on your TFS server to subscribe your service to the TFS event subscription service:
bissubscribe /eventtype WorkItemChangesEvent /address http://MyHost-w7/tfseventlistener/WorkItemSubscriber.svc /collection http://YourTfsServer:8080/tfs/YourCollectionName
The following exception bugged me while I was trying to make this service work. If you follow the above guidelines you should be fine.
The exception: 
Notification not delivered.    
Notification: WorkItemChangedEvent (DeliveryType: Soap; Address: http://MyPC/tfseventlistener/WorkItemSubscriber.svc)    Exception: System.Web.Services.Protocols.SoapException: The message with Action 'http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. 
This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver.  Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).     at Microsoft.TeamFoundation.Client.TeamFoundationClientProxyBase.ProcessHttpResponse(HttpWebResponse response, Stream responseStream, WebException webException, XmlReader& xmlResponseReader)     at Microsoft.TeamFoundation.Client.TeamFoundationClientProxyBase.ExecWebServiceRequest(HttpWebRequest request, XmlWriter requestXml, String methodName, HttpWebResponse& response)     at Microsoft.TeamFoundation.JobService.Extensions.Core.TeamFoundationNotificationClient.Notify(String eventXml, String tfsIdentityXml, Subscription subscription)     at Microsoft.TeamFoundation.JobService.Extensions.Core.NotificationJobExtension.SendSoapNotification(TeamFoundationRequestContext requestContext, TeamFoundationNotification notification, TeamFoundationIdentityService identityService)

Comments

Popular posts from this blog

WPF How to Dispose ViewModel when the associated UserControl (Not Window) closes?

C# How to unit test Dispatcher

WPF: How to Deep Copy WPF object (e.g. UIElement) ?