11/22/2024 2:52:13 PM
slxdeveloper.com
Now Live!
|
|
|
Building a SalesLogix Login Screen |
|
Description: |
Building a login screen for your custom SalesLogix addon application is an important part of building a polished and professional looking addon. This article will look at various types of login screens that you can easily build into your SalesLogix applications. (Updated for 6.2!)
|
Category: |
SalesLogix OLE DB Provider
|
Author: |
Ryan Farley
|
Submitted: |
9/15/2004
|
|
|
Stats: |
Article has been read 21429 times
|
Rating:
- 5.0 out of 5 by 3 users |
|
|
|
fiogf49gjkf0d
Building a login screen for your custom SalesLogix addon application is an important part of building a polished and professional looking addon. This article will look at various types of login screens that you can easily build into your SalesLogix applications.
There are a few different kinds of addon applications that you might build for SalesLogix which include server applications and client applications. A server application would be an application installed for a server, where the Sales Client might not be installed. An example might include a service or other process that runs to batch process data, assign leads, or some other type of server side application. As for client applications, there really are two different types. A client application that relies on and interacts with the running Sales Client and a client application that is launched independently of the running sales client. This article will focus on the latter (the first type of client application mentioned should really not have a log in screen and will be discussed in a future article). An example of this kind of client application might be an application that performs some kind of data analysis, processes sales orders, or other type of application where the user might expect it to work with SalesLogix data, but not really in context of working with the Sales Client.
Another way to look at the differences between these kinds of applications might be from the perspective of the user. If your user is a SalesLogix user that uses the Sales Client, you would want to have a login screen that reflects the information they are able to provide to log into the Sales Client. If the user is not a SalesLogix user, or the application is a server side only application then you might have a login screen that supports the information needed to log into that type of application.
Either way, your goal is to collect the necessary information so that you can build a connection string and make a connection to the SalesLogix database via the provider. Before we look at each type of login screen, let's take a look at the elements we need to collect to make a successful login.
Let's take a look at the elements we'll need for a login for a server application.
- Username
- Password
- Server
- Connection/Alias
- ReadWrite Password
(We'll get to this one later on)
Why those values? Keep in mind, this is a server application. We likely don't have the Sales Client installed. What we need to end up with is the values we need to construct a connection string (See Understanding the SalesLogix 6.2 Connection String or Understanding the OLEDB Connection String For Versions 6.1 and Prior). Let's start with providing a list of SalesLogix Servers to the user.
To obtain the list of SalesLogix servers on our local network we will use the slx_getServerList() SalesLogix procedure. To use this procedure we will need to use a special connection string. Since at this point, we don't have a username, we don't have a password. We will use this special connection string to open an OleDbConnection without authenticating.
Provider=SLXOLEDB.1;Data Source=;Initial Catalog=NO_ALIAS; Extended Properties="Port=1706;Log=On"
Let's take a look at the code that uses this connection string to establish a connection and execute the slx_getServerList procedure.
public static ArrayList GetServerList()
{
ArrayList list = new ArrayList();
string connstring = "Provider=SLXOLEDB.1;Data Source=;Initial Catalog=NO_ALIAS;
Extended Properties=\"Port=1706;Log=On\"";
OleDbConnection conn = new OleDbConnection(connstring);
try
{
conn.Open();
OleDbCommand cmd = new OleDbCommand("slx_getServerList()", conn);
OleDbDataReader r = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (r.Read())
{
list.Add(r.GetString(0));
}
r.Close();
}
catch
{
throw;
}
finally
{
conn.Dispose();
}
return list;
}
Simple enough. This code executes the procedure and fills the results in an ArrayList. If you were using old ADO from VB/VBScript then this would be returning a Recordset. Now we need to get the list of aliases on a specific server.
Once your user selects a server from your list, you will need to allow for the selection of an alias on that specific server. To obtain a list of aliases on a server we will use the sp_aliasList() SalesLogix procedure. Just as the previous code to execute the slx_GetServerList() procedure, we'll use a special connection string to make the connection.
Provider=SLXOLEDB.1;Data Source=MYSLXSERVER;Initial Catalog=NO_ALIAS; Extended Properties="Port=1706;Log=On"
This time we include the name of the SalesLogix server (this would have been selected by the user already). When we use this connection string, specifying the server name (indicated as MYSLXSERVER in the above example) and execute the sp_aliasList procedure. Let's take a look at the code.
public static ArrayList GetAliasList(string server)
{
ArrayList list = new ArrayList();
if (!server.Equals(string.Empty))
{
string connstring =
string.Format("Provider=SLXOLEDB.1;Data Source={0};Initial Catalog=NO_ALIAS;
Extended Properties=\"Port=1706;Log=On\"", server);
OleDbConnection conn = new OleDbConnection(connstring);
try
{
conn.Open();
OleDbCommand cmd = new OleDbCommand("sp_aliasList()", conn);
OleDbDataReader r = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (r.Read())
{
list.Add(r.GetString(0));
}
r.Close();
}
finally
{
conn.Dispose();
}
}
return list;
}
We now have our list of aliases on the SalesLogix server that we can present to our user. The server and alias, along with the username and password, give us all the information that we need to be able to construct a full connection string for our application to make a connection.
With the information we've now obtained from our user, we can now create a full SalesLogix Connection String.
public static string GetConnectionString(string user, string password, string server, string alias)
{
StringBuilder sb = new StringBuilder();
sb.Append("Provider=SLXOLEDB.1;");
sb.Append("User ID=");
sb.Append(user);
sb.Append(";Password=");
sb.Append(password);
sb.Append(";Initial Catalog=");
sb.Append(alias);
sb.Append(";Data Source=");
sb.Append(server);
sb.Append(";Extended Properties=\"PORT=1706;LOG=ON\"");
return sb.ToString();
}
That all great, but something is missing. The ReadWrite password. This is a required part of the connection string if you want to read and write data via this connection. Sure, you could add that to the login dialog, but you have everything you need to be able to programatically retrieve the ReadWrite password for the user (it's likely that they don't know what that password is anyway!). Luckily, you can refer to the article I wrote on that subject. Take a look at Connecting with the RWPassword From External Applications. Great. Now we can just slap all this together into a complete login for our server application.
So why won't what we just learned for server applications work for a client application? Well, technically it would work. However, these are not details that the end user is used to providing to log into a SalesLogix application. They have their username, their password, and if we're lucky they might know what the "Log in to" box is about. When you log into the Sales Client, these are the values the user provides. Chances are, they don't even know what the alias or "Log in to" box is anyway. So what we want to do is present a login screen that is similar to the Sales Client login screen. We want the user to provide their username, password, and select the alias from a list (which is the same list of aliases they see in the Sales Client login screen). That's it.
However, you don't have a procedure to get these for you. These are specific to the user on their respective machine. We'll have to dig these out of the registry.
The location where these local aliases are saved is in HKEY_CURRENT_USER under the following hive:
HKEY_CURRENT_USER Software\SalesLogix\ADOLogin
You will find there 10 defined connections. These are what you are going to display in your login box. As a side note, I should mention that there is a possibility that you'll find more than 10 listed there (but that's another article). Also there can be globally defined aliases found in HKEY_LOCAL_MACHINE under Software\SalesLogix\CUD\ADOLogin. We'll just focus on the ones found in HKEY_CURRENT_USER for this article.
Reading these values from the registry is a simple task. However, where the real value comes from is putting the peices together to contruct a connection string (along with the username and password provided by the user). If we examine the string values under each key (from Connection1 to Connection10) then we'll see the following string values:
- Alias
This is the name of the alias (ie: what is displayed on the login screen)
- Data Source
- DBPassword
- DBUser
- Extended Properties
- Initial Catalog
- Provider
If we take each of these values and bring them altogether we'll have our connection string. One thing to note here, the DBUser and DBPassword are saved if the user typed them in the connection properties dialog, however they are not used by the connection so we won't use them either (password is also encrypted and no, the SLXRWEL library won't decrypt it). We'll be getting those values from the user. What we are going to do in our code is fill an ArrayList, just as before, with the locally defined aliases. I'll create a LocalAlias class we can use to easily pass around these complete aliases to make things easier on us. The LocalAlias class will be defined as follows.
public class LocalAlias
{
public LocalAlias() {}
public LocalAlias(string name)
{
this._name = name;
}
public string Name
{
get { return this._name; }
set { this._name = value; }
}
public string DataSource
{
get { return this._datasource; }
set { this._datasource = value; }
}
public string User
{
get { return this._user; }
set { this._user = value; }
}
public string Password
{
get { return this._passwd; }
set { this._passwd = value; }
}
public string ExtendedProperties
{
get { return this._extendedprops; }
set { this._extendedprops = value; }
}
public string InitialCatalog
{
get { return this._initcatalog; }
set { this._initcatalog = value; }
}
public string Provider
{
get { return this._provider; }
set { this._provider = value; }
}
public string ConnectionString
{
get
{
StringBuilder sb = new StringBuilder();
sb.Append("Provider=");
sb.Append(_provider);
sb.Append(";User ID=");
sb.Append(_user);
sb.Append(";Password=");
sb.Append(_passwd);
sb.Append(";Data Source=");
sb.Append(_datasource);
sb.Append(";Initial Catalog=");
sb.Append(_initcatalog);
sb.Append(";Extended Properties=\"");
sb.Append(_extendedprops);
sb.Append(";\"");
return sb.ToString();
}
}
public override string ToString()
{
return this._name;
}
private string _name = string.Empty;
private string _connstr = string.Empty;
private string _datasource = string.Empty;
private string _user = string.Empty;
private string _passwd = string.Empty;
private string _extendedprops = string.Empty;
private string _initcatalog = string.Empty;
private string _provider = string.Empty;
}
The purpose of this class is to give us an easy to use class that we can simply just set the string values we get from the registry and then it will construct the string for us (we can also bind a list of these to a ComboBox. The name will show but we can get to the full connection string and any other values easily). Let's look at the code to fill these objects from the registry.
public static ArrayList GetLocalUserAliases()
{
ArrayList list = new ArrayList();
RegistryKey key = null;
try
{
key = Registry.CurrentUser.OpenSubKey(@"Software\SalesLogix\ADOLogin", false);
string[] subnames = key.GetSubKeyNames();
foreach (string name in subnames)
{
RegistryKey subkey = key.OpenSubKey(name, false);
string aliasname = (string)subkey.GetValue("Alias");
if (!aliasname.Equals(string.Empty))
{
LocalAlias alias = new LocalAlias(aliasname);
alias.DataSource = (string)subkey.GetValue("Data Source");
alias.User = (string)subkey.GetValue("DBUser");
alias.ExtendedProperties = (string)subkey.GetValue("Extended Properties");
alias.InitialCatalog = (string)subkey.GetValue("Initial Catalog");
alias.Provider = (string)subkey.GetValue("Provider");
list.Add(alias);
}
subkey.Close();
}
}
finally
{
key.Close();
}
return list;
}
That gets the list of LocalAlias objects filled for us. Now we can bind the list to a ComboBox and when the user selects one we can populate the entered username and password and read the ConnectionString property for the entire connection string. We will still have to programatically discover the ReadWrite password as before, but that's just fine.
Using this list of aliases is easy as well. We can bind it or use it to fill a ComboBox. Then when the user clicks OK on our login screen grab the LocalAlias object as the selected item on the ComboBox.
LocalAlias alias = (LocalAlias)comboAlias.SelectedItem;
alias.User = textUser.Text;
alias.Password = textPassword.Text;
string connstring = alias.ConnectionString;
This article provides a sample application that you can use to see the code outlined here in action. Take a look at the code and start building your generic and reusable login screens for your future SalesLogix addons today. See related articles section below for the sample application.
Download the sample code (C#)
Creating login screens for your applications is an important part of building a professional looking SalesLogix addon. Doing the login screen right gives a familiar way for SalesLogix users to access your application. Don't overlook this important detail. However, be smart, built it once and reuse the login screen for any application you write for SalesLogix.
Until next time, happy coding.
-Ryan
- 7/28/2005 - Updated article for SalesLogix 6.2 (Sample code for 6.1 still available, see related articles for the sample code)
|
|
|
|
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: Building a SalesLogix Login Screen Posted: 9/22/2004 4:10:43 PM | fiogf49gjkf0d I've been meaning to make a Login screen to mimic the existing screens but you beat me to the punch. I also like the way the screens were split as I would typically would use a Client login type of approach since it mimics the Administrator or Architect.
I was getting an error when I was trying to view the list of aliases on a remote machine, but the error has since went away. I don't know if it was me installing #Develop that did it, or that the person is no longer in SalesLogix but I'm going to try and run it down to figure out if it's a problem or not. Personally I'd rather fix your login screens than to try to make my own and run down it's own problems and pitfalls.
Thanks for the article. It's definately a keeper. | |
|
| Re: Building a SalesLogix Login Screen Posted: 1/24/2005 8:42:17 AM | fiogf49gjkf0d Great article. I downloaded the SLX Login Demo and ran it. However, I'm getting an error on the conn.Open(); statement. The exception is an "InvalidCastException - Specified cast is not valid". I'm also running into the same error in my own login app. Has anyone else seen this error? Could it be something in my dev environment? Any help would be greatly appreciated.
Also, I tried using the slxApplicationClass object to retrieve the connection object using GetNewConnection. I understand that it returns an object, but if I tried casting it as an oledbconnection. I get the same error mentioned above. Ditto if I try to cast to a adodb connection object.
Thanks for any suggestions. | |
|
| Re: Building a SalesLogix Login Screen Posted: 1/24/2005 10:13:58 AM | fiogf49gjkf0d The sample code is written for use with 6.1 (Note the provider in the connection strings in the code as SLXNetwork.1 instead of SLXOLEDB.1) If you are using it with SLX v6.2 then you will get the errors you mentioned (because the connection string is incomplete for 6.2 and causes the provider to throw the exception). To make the sample work with 6.2, all that is needed is to change the code that forms the connection string. If I get a chance I'll update the sample to work with 6.2 also.
As far as casting the return from the GetNewConnection of the SlxApplicationClass as an OLEDB connection, that will never work. You cannot cast an ADO Connection as an OleDbConnection.
-Ryan | |
|
| Re: Building a SalesLogix Login Screen Posted: 1/24/2005 9:57:03 PM | fiogf49gjkf0d Ryan, thanks for the response. I see your point about using the right provider. I'm using this connection string - "Provider=SLXOLEDB.1;Data Source=crm12server;Initial Catalog=SALESLOGIX_VSERVER;User ID=admin;Password=****;Persist Security Info=True;RWPASS=;Extended Properties=\"PORT=1706;Log=On\"" I got this from the SLX LAN Developer's Reference. Does it look right to you?
I noticed you mentioned that the slxApp.getNewConnection() method returns an ADO Connection object. Which version of ADO does it use? Cause I tried casting it to an ADODB.Connection class. And that threw the same exception. | |
|
| Re: Building a SalesLogix Login Screen Posted: 1/25/2005 10:37:34 AM | fiogf49gjkf0d It uses the ADO version (MDAC) that is installed with SalesLogix. I believe it's 2.6 but it may be as high as 2.8 for version 6.2. The version of ADO used doesn't really matter though as nothing has changed for a pretty long time.
Since you are connecting to the OLE DB Provider using .NET and not straight ADO, you will need to use the OleDbConnection. If you look at the function GetArrayList above the line you need is the following:
OleDbConnection conn = new OleDbConnection(connstring);
Basically if you treat ADO.NET as say version 3.0 where it is NOT backwards compatible AT ALL you'll be fine. You can't pass ADO objects to ADO.NET or vice versa. Trying to cast the GetNewConnection() return (legacy ADO) as an OleDbConnection (ADO.NET) is doing just that. | |
|
| Re: Building a SalesLogix Login Screen Posted: 1/25/2005 12:26:55 PM | fiogf49gjkf0d Unfortunately executing the following code is still throwing the invalidcastexception on the conn.Open() call.
string connstring = "Provider=SLXOLEDB.1;Data Source=crm12server;Initial Catalog=SALESLOGIX_VSERVER;User ID=admin;Password=****;Persist Security Info=True;RWPASS=;Extended Properties=\"PORT=1706;Log=On\""; OleDbConnection conn = new OleDbConnection(connstring); conn.Open();
| |
|
| Re: Building a SalesLogix Login Screen Posted: 1/25/2005 3:45:19 PM | fiogf49gjkf0d Have you pasted the 6.2 connection string into the example code and compiled that? Ryan's sample compiles and works perfectly on 6.1 so if you were to simply change the connection string to the 6.2 format it should compile and run perfectly. Regardless the example should compile as a faulty connection string won't error until you actually try to make the connection.
There's one line that might shed a little light on why this isn't working for you: "That all great, but something is missing. The ReadWrite password. This is a required part of the connection string if you want to read and write data via this connection."
The RWPASS isn't needed in this example because it simply enumerates the connection. If you want to actually manipulate SalesLogix data (i.e. select * from sysdba.account) you'll need to fill the RWPASS by looking at the article Ryan has already given on the subject titled "Connecting with the RWPassword From External Applications". I believe it's been updated for 6.2 (or that it hasn't changed).
This should be a good test to help narrow down where the problem is. I have a feeling RWPASS is the culprit but by plugging in the connection string to the sample code you should be able to easily verify if the string is bad or not. | |
|
| Re: Building a SalesLogix Login Screen Posted: 7/28/2005 5:44:20 PM | fiogf49gjkf0d Just so everyone knows, I finally got around to updating this article for SalesLogix 6.2. The sample code download has also been updated for 6.2 (the 6.1 sample code is also still available).
-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...
|
|
|
|
|
|