11/24/2024 8:21:40 PM
slxdeveloper.com
Now Live!
|
|
|
Consuming SalesLogix Data via RSS |
|
Description: |
Unless you've been hiding under a rock, you've most likely caught wind of all the buzz around blogs (weblogs) and the power behind the weblog known as RSS. RSS is a syndication format that allows you to deliver information via and XML-based channel and can be consumed in many different ways on any system. This article will examine how to create an RSS feed for new opportunity data that SalesLogix users can subscribe to to be notified of new opportunities.
|
Category: |
ASP & ASP.NET Development
|
Author: |
Ryan Farley
|
Submitted: |
4/8/2004
|
|
|
Stats: |
Article has been read 17398 times
|
Rating:
- 5.0 out of 5 by 6 users |
|
|
|
fiogf49gjkf0d
Unless you've been hiding under a rock, you've most likely caught wind of all the buzz around blogs (weblogs) and the power behind the weblog known as RSS. RSS is a syndication format that allows you to deliver information via and XML-based channel and can be consumed in many different ways on any system. This article will examine how to create an RSS feed for new opportunity data that SalesLogix users can subscribe to to be notified of new opportunities.
RSS stands for Really Simple Syndication. The concept behind information syndication allows a user to subscribe to data that they want to receive, instead of going out looking for it. It allows a user to consume information from any system - on any system. Many news sites have opted to syndicate their content via RSS. For example, you can subscribe to CNet news http://www.news.com/ via it's RSS feed here http://news.com.com/2547-1_3-0-20.xml. You can use any RSS reader to consume the information and read it when you want. Additionally, with the rampant problems with spam cluttering e-mail boxes, many sites have dropped the use of e-mail newsletters and instead gone with syndicating their information via RSS.
This article is not going to get into all the technical details around RSS feeds and the specifications for it's format. However, as long as you know that RSS is XML based and that it serves up the same way a web page does, only consumed differently, then you'll be set. There are many places you can find online that covers the RSS specification in detail so we won't cover that here.
As I stated earlier, this article will cover an RSS feed that will be used to syndicate new opportunity data to SalesLogix users. We'll make the feed so the user can specify how many entries to receive in the feed at once and also the option to pass a USERID to the feed to receive only opportunities for that user (otherwise it will return the X number of latest opportunities for all users in this example).
To create the RSS feed, we will be creating an ASP.NET page and our code will be in C# (because I am writing the article and I love C#). To keep things simple we'll just add the code to the aspx file instead of using a separate code behind class file.
Let's start with setting up the main page load and import the needed namespaces for data access and to write the XML for the feed.
<%@ Page Language="C#" %>
<%@ import Namespace="System" %>
<%@ import Namespace="System.Web" %>
<%@ import Namespace="System.Xml" %>
<%@ import Namespace="System.Text" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<script runat="server">
private const int MAXENTRIES = 100;
private void Page_Load(object sender, System.EventArgs e)
{
Response.ContentEncoding = Encoding.UTF8;
Response.ContentType = "text/xml";
// we will create this method later to render the XML
// feed to the Response stream sent back to the client
renderFeed(this.userid, this.maxentries);
}
private string userid
{
get
{
object param = Request.QueryString["userid"];
return param == null ? string.Empty : (string)param;
}
}
private int maxentries
{
get
{
object param = Request.QueryString["maxentries"];
return param == null ? MAXENTRIES : int.Parse((string)param);
}
}
</script>
Now, basically what is going on there, other than the obvious importing of namespaces, is we are setting up the encoding and the content type for the Response, which is what is sent back to the client. We've also added some properties to grab "userid" and maxentries" from the URL, or QueryString. This will allow us to have the consumer of the feed indicate how many new items they want returned. We've also added a const to indicate the default max if not otherwise specified. Another property will allow us to grab the userid value if the user wants to limit the feed to a specific user. Now, let's take a look at the meat of what generates the content for the feed and add this to the aspx file.
private void renderFeed(string userid, int maxentries)
{
// create an XML writer and supply the Response stream to output to
XmlTextWriter w = new XmlTextWriter(Response.OutputStream, null);
// start the RSS XML
w.WriteStartElement("rss"); // rss
w.WriteAttributeString("version", "2.0");
w.WriteAttributeString("xmlns", "dc", null, "http://purl.org/dc/elements/1.1/");
// add a channel with the channel information
w.WriteStartElement("channel"); // channel
w.WriteElementString("title","SalesLogix Latest Opportunities");
w.WriteElementString("link","http://www.slxdeveloper.com/scripts/slxweb.dll/home");
w.WriteElementString("description","This feed returns the latest opportunities in SalesLogix");
// create a connection to the SalesLogix database. We'll use the SqlClient, instead of the SalesLogix
// provider since we will be reading data only
SqlConnection conn = new SqlConnection(@"server=morpheus\sql2000;database=saleslogix61_eval;uid=sysdba;pwd=masterkey");
try
{
conn.Open();
// execute a DataReader to read the opportunity data
SqlCommand cmd = new SqlCommand(getOpportunitySql(userid, maxentries), conn);
SqlDataReader r = cmd.ExecuteReader(CommandBehavior.CloseConnection);
string tmp = string.Empty;
while (r.Read())
{
// start creating the individual items for the feed
w.WriteStartElement("item"); // item
w.WriteElementString("title", r["description"].ToString());
w.WriteStartElement("guid"); // guid
w.WriteAttributeString("isPermaLink","false");
w.WriteString("OpportunityID:" + r["opportunityid"].ToString());
w.WriteEndElement(); // guid
// this StringBuilder will hold the main content for each entry in the feed
StringBuilder sb = new StringBuilder();
sb.Append("The following opportunity has been created in SalesLogix:");
sb.Append("<br><hr>");
sb.Append("Opportunity: ");
sb.Append(r["description"]);
sb.Append("<br>");
sb.Append("Account manager: ");
sb.Append(r["username"]);
sb.Append("<br><br>");
sb.Append("Opportunity type: ");
sb.Append(r["type"]);
sb.Append("<br>");
tmp = r["salespotential"].ToString();
if (!tmp.Equals(string.Empty)) tmp = string.Format("{0:c}", r["salespotential"]);
sb.Append("Sales potential: ");
sb.Append(tmp);
sb.Append("<br>");
sb.Append("Account: ");
sb.Append(r["account"]);
sb.Append("<br><br>");
sb.Append("Created on: ");
sb.Append(DateTime.Parse(r["createdate"].ToString()).ToLongDateString());
sb.Append("<br><br>");
w.WriteElementString("description", sb.ToString());
tmp = DateTime.Parse(r["createdate"].ToString()).ToUniversalTime().ToString("r");
w.WriteElementString("pubDate", tmp);
w.WriteElementString("category", "Latest Opportunities");
w.WriteElementString("creator", "http://purl.org/dc/elements/1.1/", r["username"].ToString());
w.WriteEndElement(); // item
}
r.Close();
}
finally
{
conn.Dispose();
}
w.WriteEndElement(); // channel
w.WriteEndElement(); // rss
// now flush the XML writer so it is written out to the Response stream and sent to the client
w.Flush();
}
private string getOpportunitySql(string userid, int maxentries)
{
// create the SQL statement used to gather the opportunity data
StringBuilder sb = new StringBuilder();
sb.Append("select top ");
sb.Append(maxentries);
sb.Append(" o1.opportunityid, o1.accountid, a1.account, o1.description, ");
sb.Append("o1.type, o1.salespotential, u1.username, o1.createdate ");
sb.Append("from opportunity o1 ");
sb.Append("inner join account a1 on o1.accountid = a1.accountid ");
sb.Append("inner join userinfo u1 on o1.accountmanagerid = u1.userid ");
if (!userid.Equals(string.Empty))
{
sb.Append("where o1.accountmanagerid = '");
sb.Append(userid);
sb.Append("'");
}
sb.Append(" order by o1.createdate desc");
return sb.ToString();
}
Now that's a beautiful sight. Simple and easy. And you know the best part? That is it. We're done. The feed is all ready to be consumed. Let's move on a take a quick look.
There are many consumers, or readers, for RSS available. Many of them are free. Some of my favorites are:
To view the XML for the RSS feed, all we need to do is open the URL in Internet Explorer just as we would a web page. Since our RSS feed has support for some optional parameters, we can use the feed in any of the following ways:
- http://localhost/SalesLogixRSS/Rss.aspx
- http://localhost/SalesLogixRSS/Rss.aspx?maxentries=20
- http://localhost/SalesLogixRSS/Rss.aspx?userid=UAX040000001
- http://localhost/SalesLogixRSS/Rss.aspx?userid=UAX040000001&maxentries=15
Let's take a look at the raw RSS. Open the URL in Internet Explorer and the result will look like the following:
Internet Explorer does it's pretty XML structuring, but all we're getting back is our XML. Let's take a peek at how the feed looks when subscribed to in the readers mentioned earlier.
Click to enlarge view
Delivering SalesLogix data via RSS opens some enormous opportunities. You could make available to the sales team feeds detailing any new products added to the system, new library items, or new contacts or accounts that have been assigned to them. How about having a public RSS feed to pull data from SalesLogix to allow your customers to subscribe to notification of new offerings or campaigns? (Note: providing access to SalesLogix data to non-SalesLogix users requires use of an external access license to keep licensing legitimate) The possibilites are endless. Sure there are other ways to get this information out to SalesLogix users, but having RSS feeds available for this information allows the user to subscribe to the feeds that will best assist them in their jobs. And besides that, information syndication is just plain cool.
Until next time, happy coding.
-Ryan
- 4/12/2004 - Updated code sample - forgot to close DataReader and convert pubdate in XML to universal time format. Related code download also updated.
|
|
|
|
Rate This Article
|
you must log-in to rate articles. [login here] 
|
|
|
Please log in to rate article. |
|
|
Comments & Discussion
|
you must log-in to add comments. [login here]
|
|
|
- subject is missing.
- comment text is missing.
|
|
| Re: Consuming SalesLogix Data via RSS Posted: 4/8/2004 3:34:01 AM | fiogf49gjkf0d BTW, the recent articles RSS feed for slxdeveloper.com will be up next week ;-)
-Ryan | |
|
| Re: Consuming SalesLogix Data via RSS - RSS now available on slxdeveloper.com! Posted: 4/12/2004 1:08:22 AM | fiogf49gjkf0d For anyone interested, the slxdeveloper.com Latest Article RSS feed is now available at:
http://www.slxdeveloper.com/articlerss.aspx
-Ryan | |
|
| Re: Consuming SalesLogix Data via RSS Posted: 4/15/2004 1:04:03 PM | fiogf49gjkf0d Awesome. I love RSS a little too much (tons of feeds subscribed, so many I can barely keep up that it almost becomes a full time job reading them) and this is something else I really don't need to deal with but it opens up a world of possibilities.
SalesLogix should pick up on this and use it for some alert features (free possibly? finally?) but if they won't then someone like me can using this method.
Anyone who can, should use RSS as much as possible because it keeps only the important information at your fingertips. You don't have to weed through tons of useless information for those golden nuggets of information goodness. Sweet. Thanks again for the great article
-Jeremy | |
|
| Re: Consuming SalesLogix Data via RSS Posted: 4/15/2004 1:15:42 PM | fiogf49gjkf0d Thanks Jeremy,
I agree. RSS is just too awesome. The wave of the future. I'm almost to the point now where I open my RSS reader more often than my browser! It is great to decide what information you want and just subscribe so it comes to you instead of going out looking for it. I've got my own custom feeds running all over my network. I've got a feed that notifies my wife of new Mp3's I've added to my collection, an Windows Event Log feed so I can subscribe to new entries in the logs on remote web servers I monitor, and just about anything you can think of.
I'd love to see some of this kind of stuff built into the Web Client. Make it so a user can be notified of things happening in the database on a subscription basis - so they can choose which information they want to see. And you could easily make it so the feeds use the userid to limit it to the data they have access to.
I am an RSS fiend. -Ryan | |
|
| Re: Consuming SalesLogix Data via RSS Posted: 9/9/2004 3:51:28 PM | fiogf49gjkf0d Ryan,
I just got around to reading this article and it's really an awesome idea. As I'm about to embark on a project which involves providing data to customers (non-users), and the only option is seemingly the customer service portal (with lots of customization), I really need to take a long look at how I might pump information out to these people. Heck, I may rethink mail merged newsletters all together!!
Question: How can I ensure that a saavy consumer doesn't strip out an ID that I've embedded in their feed url? Gotta comply with HIPAA and all that...
MikeB | |
|
| Re: Consuming SalesLogix Data via RSS Posted: 9/9/2004 4:13:28 PM | fiogf49gjkf0d Mike,
You could control that (enforcing rules that disallow URLs where the ID has been stripped out) easily in the code. You'd simply add code that checks for the ID value passed in the QueryString and in the case where it is missing you'd return back a single item containing a message that said something to indicate to contact your company for a proper URL.
Another option is to use authentication of some kind. RSS does support all standard HTTP authentication mechanisms, the same way you'd secure a web page. You just have to make sure you use a reader that supports it also (which most do). You could do something that route and the ID wouldn't be needed at all since you could just display the data based on the authenticated user.
BTW, RSS is the way to go for something as you described. That is the kind of scenario that it is intended for. Far better than mass e-mailing, faxing, etc. However, some people are still behind the tech-curve when it comes to RSS, so it is not a bad idea to provide an alternate route also.
-Ryan | |
|
|
|
|
|
Visit the slxdeveloper.com Community Forums!
Not finding the information you need here? Try the forums! Get help from others in the community, share your expertise, get what you need from the slxdeveloper.com community. Go to the forums...
|
|
|
|
|
|