Notification Services – Part 4 – Managed API
In the first 3 parts of this series we discovered how to define a Notification Services application via the instance and application XML. In part 2 we defined an example scenario where users are automatically subscribed to receive notifications in their email whenever someone posts a comment against their blog post. In this part we will discover how to write code to access the event schemas we defined in part 3, and how to insert subscribers. For the sake of brevity, this post will define sections of code, not entire classes. Assume a class library project in C# that will be called by our main blog ASP.NET application. The methods defined in this post would be found in such a library.
This post assumes that the Notification Services instance is installed on the same machine that will be running the code. This is important because to access a NS instance, you don’t use connection strings as is typical in ADO.NET. Instead, it refers to registry entries which are automatically placed by NS when the instances is ‘Registered’ and ‘Started’. For more information, see the MSDN link.
Preperation
Our class library project will need access to the Notification Services libraries in order to communicate with Notification Services. You can add this through references. The assembly file name is Microsoft.SqlServer.NotificationServices.dll. This assembly is installed in the GAC when Notification Services is installed (with SQL Server).
At some stage we will also need to define what our Instance name and Application name is. We could put this in a constant but ideally it would be in web.config and accessible through a property somewhere. This code will assume a class called ‘Settings’ which has properties called ‘InstanceName’ and ‘ApplicationName’. Eg. string application = Settings.ApplicationName;
A lot of the time we will need access to an instance of a class called NSInstance. Through this class we can get access to our NS application, by getting an instance of NSApplication. The rest of this post will refer to instances of both of these classes, so we will define some code for them now:
NSInstance BlogInstance = new NSInstance(Settings.InstanceName);
NSApplication BlogApplication =
new NSApplication(BlogInstance, Settings.ApplicationName);
In Notification Services an instance can have multiple applications, even though previously we have defined only 1.
Subscribers
First we’ll define some methods for subscribing and unsubscribing users. Before we do this, we need to think about how authentication is tracked. For simplicity sake, we will assume that users are authenticated by active directory. This means the current windows principal will provide us with a username as a string:
string userId = WindowsIdentity.GetCurrent().Name;
You may remember from our application schemas that we needed to store a UserId. This was a simple string that represents the user a subscription belongs to. Before we can add subscriptions, we need to first check that the instance has the user registered as a subscriber. We can do this as follows:
public bool Exists(string userId) {
SubscriberEnumeration mySubscriberEnumeration =
new SubscriberEnumeration(BlogInstance);
Subscriber mySubscriber = mySubscriberEnumeration[userId];
return (mySubscriber != null);
}
As you can see we use our BlogInstance to access an enumeration of all users, which can be indexed by the user’s name. We could easily modify this into a Delete method for a subscriber as follows:
if (mySubscriber != null) mySubscriber.Delete();
Now we know how to check for a subscriber, we can write code to add one:
if (Exists(userId)==false) {
Subscriber subscriber = new Subscriber(BlogInstance);
subscriber.Enabled = true;
subscriber.SubscriberId = userId;
subscriber.Add();
}
Simple! If we don’t check for a subscriber first, an exception will occur if a name is added twice.
Devices
In my last post I discussed Devices very quickly. Devices allow you to specify different delivery locations for different subscriptions. For example, I might want to receive notifications by email and instant message. We need to define a device for our subscriptions to be allocated against:
SubscriberDevice device = new SubscriberDevice(BlogInstance);
device.DeviceName = "WorkEmail";
device.SubscriberId = userId;
device.DeviceTypeName = "Email";
device.DeviceAddress = "myrealemailaddress@hotmail.com";
device.DeliveryChannelName = "SMTP";
device.Add();
DeviceName is often referenced in your application XML rule for subscriptions so it is usually important to have a naming standard for your devices. However we have not been using devices up to this point so the values you put here aren’t important for now.
DeliveryChannelName however is extremely important. In part 2 we defined the instance XML and part of that was the <DeliveryChannels>. In that XML we defined a protocol of type SMTPDelivery with a name of SMTP. When defining the device delivery channel name, it must match one of the channels specified in your instance XML otherwise no deliveries will be sent (no exception will occur, however when the service runs your notifications, it is at this point that it will fail, and details will be inserted into the event log).
As with subscribers you can check if the device has already been added as follows:
SubscriberDeviceEnumeration deviceEnumeration =
new SubscriberDeviceEnumeration(BlogInstance, userId);
SubscriberDevice mySubscriberDevice = deviceEnumeration ["WorkEmail"];
return (mySubscriberDevice != null);
As with subscribers, we should check the device has not already been added before commencing the insert process. And as with subscribers, deleting a device is as easy as calling the Delete method of the SubscriberDevice instance.
Subscriptions
Since we are only concerned with adding a subscription, the code for this is reasonably simple. Remember our requirements originally stated that a user will be automatically subscribed to a post after the post is created. This means we don’t even need to check if the user is already subscribed since they couldn’t possibly be. This makes our code even easier. Here is what the add method might look like:
public void Add(string userId, string deviceName, int PostId) {
Subscription subscription =
new Subscription(BlogApplication, "CommentSubscription");
subscription.SetFieldValue("DeviceName", "WorkEmail");
subscription.SetFieldValue("SubscriberLocale", "en-au");
subscription.SubscriberId = userId;
subscription.SetFieldValue("PostId", PostId);
subscription.Add();
}
Because the .Net type subscription has no way of knowing at design-time what fields your subscription schema might have, it uses a common method for setting your subscription fields. This means you won’t get compile errors if you don’t really have a "PostId" in your subscription schema in Notification Services, but you will get a runtime exception on the subscription.Add(); method call.
Important to note is that in the constructor for a Subscription takes an NSApplication instance now. This is because even though subscribers and devices are specific to an instance, an actual subscription is specific to an application only. Also note the second parameter of the constructor. This is the name of the subscription class we are subscribing to. Note that the name we supplied ‘CommentSubscription’ is the name we specified for our subscription class in the application XML. Once again, this will cause a runtime exception at the subscription.Add(); method call if the subscription class name is invalid.
Well done! The user is now subscribed to receive notifications when comments are posted. However we still have to define how comments are posted to Notification Services so that those subscriptions can be acted upon.
Events
Going back to our Events schema defined in our application XML, there is a number of fields we need to supply information for. The Event class helps us set values for those fields very easily, just like it does for subscriptions. To add an event to Notification Services is as easy as this:
Event event = new Event(BlogApplication, "NewCommentEvent");
event["PostId"] = postId;
event["Name"] = CommentPosterUserName;
event["Details"] = CommentText;EventCollector eventCollector =
new EventCollector(BlogApplication, "BlogEventsProvider");
eventCollector.Write(event);
In this code, we assume that we already have the values of the comment text, the user who posted the comment, and the original blog postId that the comment was posted against. The Event class lets us define the details to post to Notification Services through an indexer, and the EventCollector class will write the events to Notification Services for us. As usual incorrect fields specified will result in a runtime exception.
Some items to note here. First, the constructor for an event needs the name of the event class we are posting to. We only defined 1 in our events schema; this was defined in the last post in our application XML. Secondly, in our last post we also defined the <Providers> node and the <NonHostedProvider> sub node (right at the end). When defining an EventCollector we must pass our provider name to the contstructor. You can not post an event to Notification Services without using one of the providers specified in your application XML. Because we are specifying events in code outside of Notification Services, our provider is a ‘NonHostedProvider’: not hosted by Notification Services.
Summary
Well that’s it. We call the events to post a subscription in the very next line of code after we post our blog entry. And we call our event method whenever someone posts a comment against a blog entry. And Notification Services will take care of the rest.
This brings us to the end of my series on Notification Services. If there is anything else you would like to know about, please don’t hesitate to contact me and I’ll do my best to provide useful information.
Notification Services Series
Notification Services – Part 1 – Technology Overview
Notification Services – Part 2 – Example Overview and Instance XML
Notification Services – Part 3 – Application XML
Notification Services – Part 4 – Managed API
Further Resources
Notification Services tutorial: http://msdn2.microsoft.com/en-au/library/ms170337.aspx
MSDN help: http://msdn2.microsoft.com/en-au/library/ms172483.aspx
API reference: http://msdn2.microsoft.com/en-au/library/microsoft.sqlserver.notificationservices.aspx
Hi Steven,
This is great material you\’ve generated on Notification Services. It\’s important, however, to get the message out that in the next version of SQL Server, it\’s not deprecated, it\’s gone. It shouldn\’t be used for any new development work.
Regards,
Greg
Hi,Do you need advertising displays, screen advertisings, digital sign, digital signages and LCDs? Please go Here:www.amberdigital.com.hk(Amberdigital).we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.
amberdigital Contact Us
E-mail:sstar@netvigator.com
website:www.amberdigital.com.hk
alibaba:amberdigital.en.alibaba.com[cbigeedaadie
Hi,Do you need advertising displays, digital signages, advertising player and LCD displays? Please go Here:www.amberdigital.com.hk(Amberdigital).we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.
amberdigital Contact Us
website:www.amberdigital.com.hk
alibaba:amberdigital.en.alibaba.com[bajjejieghbcacb]