|
I have a web service installed on my local IIS. I can access it via IE. But TFS does not comsume it. How do I go about seeing what the TFS eventService is trying to do?
I am pasting the Subscription (which I ran before changing a work item in the IDE) and my web service code (both cut from a blog referenced on this forum). Thanks in advance for any debuging suggestion.
Subscription...
static void Main(string[] args)
{
// Connect to TFS
TeamFoundationServer tfsServer = TeamFoundationServerFactory.GetServer("crvl1-3s184");
//TeamFoundationServer tfsServer = TeamFoundationServerFactory.GetServer
// (ConfigurationManager.AppSettings["crvl1-32184"], new UICredentialsProvider());
tfsServer.Authenticate();
// Get Eventing Service
IEventService eventService = (IEventService)tfsServer.GetService(typeof(IEventService));
// Set delivery preferences
DeliveryPreference dPref = new DeliveryPreference();
dPref.Schedule = DeliverySchedule.Immediate;
//dPref.Address = ConfigurationManager.AppSettings["WSAdress"];
dPref.Address = "http://POOR-D009943/CCWFPM_NotificationClerk/CCWFPM_NotificationClerk.asmx/";
dPref.Type = DeliveryType.Soap;
// Subscribe to event
//string userId = ConfigurationManager.AppSettings["Subscriber"];
string userId = "rdufur";
string filter = String.Empty;
eventService.SubscribeEvent(userId, "WorkItemChangedEvent", filter, dPref).ToString();
}
Web Service
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Net.Mail;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.Xml;
using System.Configuration;
using System.DirectoryServices;
[ WebService(Namespace = "http://CC.WF.PM/")]
[ WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class NotificationClerk : System.Web.Services.WebService
{
public int intCount
{
get { return (Application["Count"] == null)? 0: (int)Application["Count"]; }
set { Application["Count"] = value; }
}
[ SoapDocumentMethod(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", RequestNamespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
[ WebMethod]
public void Notify(string eventXml, string tfsIdentityXml)
{
++intCount;
// Load the recieved XML into a XMLDocument
XmlDocument eventXmlDoc = new XmlDocument();
eventXmlDoc.LoadXml(eventXml);
XmlElement eventData = eventXmlDoc.DocumentElement;
// Validate event data
if (eventData != null && ValidateEventData(eventData))
{
// Get assigned user's name from event data
string toName = GetDisplayName(eventData);
// Retrieve assigned user's e-mail address from Active Directory
string toAddress = GetAddress(toName);
// If the e-mail addres was found in AD, send the e-mail
if (toAddress != String.Empty)
SendMail( new MailAddress(toAddress, toName), eventData, GetBody(eventXml));
}
}
[ WebMethod]
public int GetCount()
{
return intCount;
}
private string GetAddress(string userDisplayName)
{
// Bind DirectorySearcher to current domain
DirectorySearcher searcher = new DirectorySearcher();
// We only need user email
searcher.PropertiesToLoad.Add( "mail");
// Set the filters. We only want Users whose Display Name is userDisplayName
searcher.Filter = String.Format("(&(displayName={0})(objectCategory=person)((objectClass=user)))", userDisplayName);
// Retrieve results
SearchResultCollection results = searcher.FindAll();
// Check if the user was found
if (results.Count > 0)
{
// Check if the user has the email set in AD
ResultPropertyValueCollection values = results[0].Properties["mail"];
if (values.Count > 0)
return values[0].ToString();
else
return String.Empty;
}
else
return String.Empty;
}
private string GetBody(string eventXml)
{
// Load XSL
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(Server.MapPath( ConfigurationManager.AppSettings["MailXSL"]));
// Create XPathDocument with event data
XPathDocument xpathDoc = new XPathDocument(new StringReader(eventXml));
// Make the transformation
MemoryStream stream = new MemoryStream();
xslt.Transform(xpathDoc, new XmlTextWriter(stream, Encoding.UTF8));
return Encoding.UTF8.GetString(stream.ToArray());
}
private void SendMail(MailAddress to, XmlElement eventData, string body)
{
MailMessage mail = new MailMessage(
new MailAddress(ConfigurationManager.AppSettings["MailAddressFrom"], ConfigurationManager.AppSettings["MailFromName"]),
to
);
mail.Body = body;
mail.IsBodyHtml = true;
// Get data for the ReplyTo address
string fromName = GetChangedBy(eventData);
string fromAddress = GetAddress(fromName);
if (fromAddress != String.Empty)
mail.ReplyTo = new MailAddress(fromAddress, fromName);
mail.Subject = String.Format("{0} assigned you a {1}", fromName, GetWorkItemType(eventData).ToLower());
SmtpClient smtp = new SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
smtp.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["SMTPUser"], ConfigurationManager.AppSettings["SMTPPassword"]);
smtp.Send(mail);
}
private string GetWorkItemType(XmlElement eventData)
{
return eventData.SelectSingleNode("CoreFields/StringFields/Field[ReferenceName='System.WorkItemType']/NewValue").InnerText;
}
private string GetChangedBy(XmlElement eventData)
{
return eventData.SelectSingleNode("CoreFields/StringFields/Field[ReferenceName='System.ChangedBy']/NewValue").InnerText;
}
private string GetDisplayName(XmlElement eventData)
{
return eventData.SelectSingleNode("CoreFields/StringFields/Field[ReferenceName='System.AssignedTo']/NewValue").InnerText;
}
private bool ValidateEventData(XmlElement eventData)
{
// Check if the Assigned To field changed
XmlNode assignedTo = eventData.SelectSingleNode("ChangedFields/StringFields/Field[ReferenceName='System.AssignedTo']");
if (assignedTo != null)
{
// Check that the assigned user is different to the user that changed the work item
XmlNode changedBy = eventData.SelectSingleNode("CoreFields/StringFields/Field[ReferenceName='System.ChangedBy']");
return (assignedTo.SelectSingleNode("NewValue").InnerText != changedBy.SelectSingleNode("NewValue").InnerText);
}
else
return false;
}
}
Note: I am using the GetCount webmethod to chech to see if it got a event notification. |