Programming, technology, and CRM – from a Belgian programmer exiled to Missouri
  • rss
  • Home
  • Soft Gallery
    • autosvnbackup.sh
    • VBScript Snippets
  • Contact Me
  • Welcome

Step by Step Guide to Custom Form Development with Visual Studio

Nicolas Galler | December 15, 2009

I think I just made the longest post ever on the SalesLogix Journal. It is a fairly complete guide on how to get started writing custom smart parts for SalesLogix in Visual Studio. I think it is a bit scary to get started with those but it is a must to provide rich functionality (for better or worse – but I think it is a good thing that Sage is not trying to cram every possible functionality into the QuickForms – their job is not to create a Visual Studio replacement!!)

Anyway, I might start writing most of the SalesLogix content through that channel so this blog does not look so much like a SalesLogix reference guide :)

Comments
No Comments »
Categories
Uncategorized
Comments rss Comments rss
Trackback Trackback

How to refresh tabs, from the client side (SalesLogix 7.5.2)

Nicolas Galler | December 11, 2009

As part of the many performance enhancement brought by this latest service pack, tabs are no longer automatically refreshing when a dialog closes. I think we can all agree that the gained performance is worth it :) But this has a few consequences:

  • First of all, if you are using a quickform as an insert form, you are all good. Yes, this is one of these cases where using a quickform actually paid off! Congratulate yourself for the good choice.
  • If you are using a custom smart part processed on the server side, it is quite straightforward, but requires a manual addition of this little piece of code to your server side script (right before or after closing the dialog):

    PanelRefresh.RefreshTabWorkspace();
  • If you are using a client-side customization (and I do use those once in a while for interactive or time-consuming processes), it is only slightly more complex – you need to trigger a refresh from the client side. Assuming you are closing the dialog with this type of code:
    DialogWorkspace._dialog.close();

    In that case I had to use a slight subterfuge to get the panel to refresh correctly. I added a hidden (server-side) button on the page:

    <asp:Button runat="server" ID="btnProcessServer" CssClass="btnProcess_server" style="display: none" />

    And then in the code-behind:

    /// <summary>
    /// This is called by the Javascript when processing is complete.
    /// Close the dialog, and ensure tab is refreshed.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void btnProcessServer_Click(object sender, EventArgs e)
    {
        DialogService.CloseEventHappened(sender, e);
        PanelRefresh.RefreshTabWorkspace();
    }

    Finally I just had to replace my javascript with the following to cause a postback and have the dialog closed from the code-behind from the button:

    $(".btnProcess_Server").click();

    Note that I am using the CSS class instead of the id, as the id is going to be transformed a bit by ASP.NET. It’s a bit of a cheat. There might be a creative way to do it entirely from client side, using the window.TabControl object (a reference to the tab workspace), however experience taught me creatively discovering hidden Sage Javascript API is a good way to waste my afternoon (and also get my butt kicked during upgrades!)

Comments
No Comments »
Categories
Saleslogix
Comments rss Comments rss
Trackback Trackback

Automatically importing default SalesLogix namespaces for C# code snippets

Nicolas Galler | December 8, 2009

When working on web client forms you may have seen this error:


e:\inetpub\wwwroot\PhysicianLiaison\SlxClient\SmartParts\Contact\ContactDetails.ascx(678): error CS0246: The type or namespace name 'IContact' could not be found (are you missing a using directive or an assembly reference?)

For example this happens when you use an unqualified reference in a C# code snippet, such as:


var myContact = (IContact)BindingSource.Current

You can’t add a “using” statement so the work around is to qualify all references:


var myContact = (Sage.Entity.Interfaces.IContact)BindingSource.Current

To save on the typing, you can add a default import to your web.config file. Simply do a search for “<pages>” and add the following under that tag (or if you don’t see a <pages> tag at all, add it under <system.web>):


<namespaces>
<add namespace="Sage.Entity.Interfaces"/>
</namespaces>

Of course this can be used with your custom namespaces as well. If you are using extension methods to define business rules (as explained in Easy Business Rules with Extension Methods) it will let you use those too.

Comments
No Comments »
Categories
Saleslogix
Comments rss Comments rss
Trackback Trackback

Make sure you disable debugging in production!

Nicolas Galler | December 2, 2009

Here is a quickie… Several times I have made the mistake of shipping a web.config with debugging enabled (fortunately always caught it at the last minute so far). This has a horrible affect on performance because it prevents caching. It can also cause some serious memory issues under heavy load. So I made myself a big warning on the login page:

Big old warning

The code for it looks like this (in Login.aspx):

    </asp:Login>
    <asp:Label style="clear: both; display: block; width: 100%; text-align: center; color: red; font-size: 24pt" runat="server" id="lblDebugWarning"
                Text="Debugging Enabled in web.config - Set to False for Production" />
</asp:Content>

And under Page_Load, very simple:

    protected void Page_Load(object sender, EventArgs e)
    {
        lblDebugWarning.Visible = HttpContext.Current.IsDebuggingEnabled;
        System.Web.UI.WebControls.CheckBox rememberMe = (System.Web.UI.WebControls.CheckBox)slxLogin.Controls[0].FindControl("chkRememberMe");

By the way it slightly funks up the display for IE6 – but only when the label is actually displayed, so not a big deal.

Comments
No Comments »
Categories
Saleslogix
Comments rss Comments rss
Trackback Trackback

Why I switched to Linux for Saleslogix Development

Nicolas Galler | December 2, 2009

This seemed like a no-brainer. SalesLogix is a Windows application, all the development tools run exclusively on Windows, and even though it does support a Linux database server (with Oracle) the vast majority of our customers are even running their database server on Windows. Nevertheless, Windows as a developer’s desktop has some serious issues (even more so for SalesLogix-specific development) and after realizing that I was spending most of my time inside of virtual machines anyway to work around 64-bit and IIS7 issues (and to take a break from Vista’s constant security nags), I decided to run a little experiment to see exactly how usable (or not) using Linux as a desktop for development of a Windows-based program would be. I loaded a copy of Ubuntu Linux on my workstation and started experimenting – I used the Linux desktop for email, web and editing, and used VirtualBox images for SalesLogix development.

The results? Well, they are in the title of the post! I don’t know if the Linux desktop will be a permanent thing on my home computer but it is definitely a big benefit on my work machine. It turns out that:

  • Installation and updates is quite a lot easier thanks to the built-in package manager – no need to look for, install and keep up to date 2 dozens third party programs because everything is included
  • The desktop has a few neat features that make it a perfect work environment – virtual desktops is the big one for me, it basically emulates additional monitors. The mouse focus is also nicer (you can get those effects with 3rd party programs and tweaks on Windows but not as well integrated). All in all the desktop is a bit more comfortable to me – could be because I was already quite familiar with it though.
  • A lot of neat and actually useful toys that come with the box. For example, there is a widget to which you can paste images to send them directly to an image sharing site – it’s great for posting screenshots on the SLX forums. Or a sticky note app (there is one in Windows 7 too but it is not terribly useful for me as it can’t sync between computers). Again, because they come with the system I do not need to spend additional time looking for them and keeping them up to date.
  • 32bit vs 64bit issues are non-existent – no “WoW64″ here. Oh, the sweet relief. I believe it was all worth it just to get rid of that nightmare.
  • Git. Git is not that slow on Windows, in fact it is a lot faster than the alternatives. But the first few times I ran it on Linux it happened so fast I thought there was a bug and it was not picking up my changes. I am not exaggerating – a local git clone of a Saleslogix repo goes down from 30 to 2 seconds. The integration with the merge tools is also better (a lot better). So now when I need to do a big merge I bring the repo to my Linux filesystem, do the merge, and send it back. Words fail to express how much more pleasant this is.
  • Warm fuzzy feeling from using an open source OS? Maybe :)

Now to be fair not everything is rosy… First of all be prepared for a fairly steep learning curve if you have no experience with Unix at all. To make things worse there are usually 2 ways to do most things – the “intuitive” way, through the UI, which takes a lot of clicks and is not always terribly reliable (though usually about the same as what it would be on Windows), and the “easy (not)” way, through the command line, which is very fast but requires you to know what you are doing. Even so, some operations require a bit of Googling and gentle coaxing – for example installing and configuring the NVidia driver for multiple monitors was not quite a point-and-click operation. A lot of the desktop functions are not extremely stable or polished – for example, the file browser crashes on me every few days, the UI stutters a bit when doing a disk-intensive operation (though it has no problem coping with the memory pressure of having 6 VMs running at a time, unlike Windows), Adobe Flash applications don’t always work fine, and because some of the fonts available on Windows are not present some web pages display incorrectly. And external devices are usually not “officially” supported – I have had good luck so far (I am actually able to customize all of my keyboard buttons which is better than what I could do in Windows, and my older scanner which does not have a Vista driver works fine on Linux) but I am sure esoteric USB devices or certain graphic cards might cause some issues. Well, these are the reasons I am still not quite sure I will keep it as a desktop OS for my home computer.

More importantly for work and development, while the integration with the Windows file shares is good, it is not perfect – sometimes I have to copy a file to my system, edit it, then copy it back. And I do miss Outlook (not that it is a fantastic program in itself – but the level of integration with Exchange is great). If I was using the Outlook calendar a lot I might be very unhappy – as it is I manage fine from my Blackberry.

My conclusion is not to encourage anyone to switch to Linux. Rather, an invitation to keep your mind open, as the ideal solution may not always be the obvious one!

Linux Desktop

PS: I opened an alternate blog at Nico’s Linux with the Linux-specific stuff, since it is not directly related to CRM.

Comments
No Comments »
Categories
Experiments, Saleslogix
Comments rss Comments rss
Trackback Trackback

Useful web development tools

Nicolas Galler | October 25, 2009

What are the tools you use every day… or at least on a very regular basis for web development? I sat down and made a list… leaving out the obvious Visual Studio and the stuff that was more specific to .NET (Reflector, windbg etc):

  • IETester – great for testing display of different IE version without switching between 3 vms
  • jsmin to minimize / combine javascript
  • Firebug and/or IE8 developer tools… duh! Can’t get very far without one of those any more.
  • IE7 developer tools – they tend to crash a lot on SlxWeb so I only use them when I need to troubleshoot an IE7-specific problem
  • Sizer – very useful to see what the page looks like at various resolutions
  • Fiddler – to snoop http… very neat
  • Tamper Data – Firefox extension to troubleshoot HTTP headers etc, sometimes I use it instead of Fiddler, or when I am on Linux. Fiddler is a lot more user friendly but it does not let you edit the headers on the fly.
  • Wireshark – a TCP capture tool… for when Fiddler is not enough! Thankfully I don’t have to use that one very often.
  • ScreenRuler for Gnome: this is Linux-specific but I am sure Windows equivalents exist – it pops a virtual ruler on the screen. Very handy when trying to align controls

And a few others that are not strictly web tools, but still extremely useful in web development:

  • KDiff3 – a diff tool. There are a number of other diff tools. WinMerge is a bit easier to use but I had trouble with some files with it (something to do with the newline styles, I think).
  • Notepad2 – a notepad replacement with syntax highlighting and other features. I use it a lot to peek at source files because it loads about 1000 times faster than Visual Studio (and even a lot faster than Vim)
  • Source control is a must: I use Git (actually msysgit, for Windows) for SlxWeb development and Subversion for most other projects. Subversion is a lot easier to use but does not work well for SlxWeb.
  • VirtualBox – I tried VMWare and VirtualPC as well, but the free versions of VMWare are very limited, and I found VirtualPC to have very poor performance.
Comments
2 Comments »
Categories
Programming
Comments rss Comments rss
Trackback Trackback

Simple Picklist – Enabling Picklist manager options for the web client

Nicolas Galler | October 5, 2009

One missing feature of the SLX web client some of our users have been very vocal about is the ability to manage picklist options (multi-select, alphabetical sort, etc) from the good old picklist manager.  What makes it even more confusing is that there is no indication in the picklist manager that the options are not actually going to take effect… but in fact in the web client these options are only taken from the picklist control itself (i.e., set via the App Architect or in the page’s code). 

Fortunately it is a reasonably simple problem to resolve since those picklist options are readily accessible from the database.  All we have to do really is wrap the creation of the picklist control with something that will know how to pull that info and set it on the control.  The simplest way to do that would probably be to subclass the control, but I decided to go with a decorator pattern instead (the idea was that this would let me change a bit more of the behavior, for example, replace the stock picklist with a regular dropdown).  So instead of using:

<SalesLogix:PickListControl runat="server" ID="pklType" PickListName="Account Type" AutoPostBack="true"  AlphaSort="true" MustExistInList="true" AllowMultiple="true"  />

I use:

<SSS:SimplePickList runat="server" ID="pklType" PickListName="Account Type" AutoPostBack="true"   />

Behind the scene the SimplePicklist controls reads the attributes from the database and create a Saleslogix picklist control with the proper settings, something like this:

_picklist = new PickListControl();
if ((_storageMode & PicklistStorageMode.Id) != 0)
    _picklist.StorageMode = Sage.Platform.Controls.StorageModeEnum.ID;
else if ((_storageMode & PicklistStorageMode.Code) != 0)
    _picklist.StorageMode = Sage.Platform.Controls.StorageModeEnum.Code;
_picklist.PickListName = _picklistName;
_picklist.AllowMultiples = _attr.AllowMultiples;
_picklist.AlphaSort = _attr.AlphaSorted;
_picklist.NoneEditable = _attr.NoneEditable;
_picklist.Required = _attr.Required;
_picklist.MustExistInList = _attr.ValueMustExist;
_picklist.PickListValueChanged += delegate
{
    if (TextChanged != null)
        TextChanged(this, EventArgs.Empty);
};
parentControl.Controls.Add(_picklist);

This works fine for custom smart parts, how about for QuickForms?  Well, it is possible to change the template there too, but as it is global (will affect nearly every picklist in the client) it is a bit scarier :)

In the Model\QuickForms\Web\QFSLXPickList.WebControlRenderingTemplate.vm I changed the control to use my “SimplePickList” instead of a PickListControl

## Simple Picklist alternative (to automatically determine the sort etc)
    <SSS:SimplePickList Compatible="true" runat="server" ID="${qfcontrol.ControlId}" #if($qfcontrol.IsReadOnly)ReadOnly="true" #end
#if(!$qfcontrol.Enabled)Enabled="false" #end
#if($qfcontrol.ToolTip != "") ToolTip="<%$ resources: ${qfcontrol.ControlId}.ToolTip %>" #end
#if($qfcontrol.HotKey != "")AccessKey="$qfcontrol.HotKey" #end
#if($qfcontrol.PickListName != "")PickListName="$qfcontrol.PickListName" #end
#if($qfcontrol.HasActionCode || $qfcontrol.AutoPostBack)AutoPostBack="true" #end
#if($qfcontrol.Required)Required="true" #end
#if($qfcontrol.MaxLength > 0)MaxLength="$qfcontrol.MaxLength" #end
#if($qfcontrol.TabIndex > 0)TabIndex="$qfcontrol.TabIndex" #end
#if($qfcontrol.StorageMode != "Text")StorageMode="$qfcontrol.StorageMode" #end
#if($qfcontrol.StyleScheme != "")CssClass="$qfcontrol.StyleScheme" #end
#if(!$qfcontrol.Visible)Visible="false" #end  />

The “Compatible=true” setting is something I added to avoid bad surprises – it forces the list to display as a standard Saleslogix picklist, instead of e.g. a dropdown.

Now because it is a custom control, it requires a change to web.config too, something like this (under system.web/pages/controls):

<add tagPrefix="SSS" namespace="SSSWorld.Slx75.Web.Controls" assembly="SSSWorld.Slx75"/>

I think it works great, but haven’t tried on a production system yet – I am going to save it for a next big project when I can get a resource to QA the entire app!  I do already use the “small” version in production in my custom smart parts, though.  I saved the code under here, if interested feel free to rip it up (though it probably has some extra dependencies so it will require a bit of cleanup).

So although I think the PickListControl should support this out of the box it is nice to see that it is not too hard to add the functionality ourselves.

Comments
2 Comments »
Categories
Uncategorized
Comments rss Comments rss
Trackback Trackback

Saleslogix bandwidth saver – store viewstate in Session

Nicolas Galler | September 12, 2009

As I try to optimize the bandwidth on the site using caching, compression etc it still remains very high.  There are substantial improvements on that front in the upcoming SP2 but that does not mean those of us stuck in the present are completely helpless.  If you use a tool such as fiddler to analyze the traffic on a postback (for example, when you change the account type – which does not actually result in any visible change on the UI) you may see something like (note, this is uncompressed):

Request Count:     1
Bytes Sent:     17,790
Bytes Received: 184,648

That’s a pretty big chunk – both on the way in and out.

For comparison here is gmail when I browse from message to message (uncompressed):

Request Count:     1
Bytes Sent:     1,295
Bytes Received: 7,521

Well part of it is just the nature of the ASP.NET UpdatePanel – they practically resend the whole page every time so it is bound to take a good bit more space.  But another culprit is the ViewState – this is something that ASP.NET uses to “remember” what is displayed on the browser (since fundamentally, the web is stateless – if you say you want to view the 3rd row in the grid, the server has to have some way to remember what this 3rd row is pointing to).  What happens is the server takes all (or most) of the values on the page, and their corresponding data sources, serializes them to text, and stick them in a hidden field on the page as something like this:

/wEPDwUENTM4MQ9kFgJmD2QWAgIBD2QWDgICDw8WAh4EVGV4dAUOTmljb2xhcyBHYWxsZXJkZAIGDw8WBB4IQ3NzQ2xhc3MFBk5hdkJhch4/wEPDwUENTM4MQ9kFgJmD2QWAgIBD2QWDgICDw8WAh4EVGc+bDAwJFRhYkNvbnRyb2wkZWxlb …  11000 more characters in between … 9nZE+NljKHHLWlju6N/3/hWmlJpeFXEXyFTQgICZGQCDA9kFgQCAQ9kFgJmD2QWAgIBD2QWAmYPZBYgAgEPDxYEHglNYXhMZW5ndGgCgAEfAAUZQ2VhWmlJpeFX

So you have 11 to 30 kb of “stuff” to pass back and forth on each and every post, not to mention the valuable CPU it takes to serialize and deserialize it.  Usually it is rather neat to have it on the browser rather than on the server because it means if your session is torn (for example because the web server restarted) you will keep this viewstate.  However this is rather moot on Saleslogix since the user is kicked out in that event anyway… so why not leave it on the server in the first place?  Turns out Microsoft thought of that too and they provided us with a way to store the ViewState in the session.  Saves the bandwidth and the CPU time to handle it (session values are stored “as-is” in memory so it is pretty fast).  There are posts describing the process here and here – I am including both because I took an in-between approach.  Once I did that I reduced the ViewState to this (it still needs a key to be able to look up the viewstate in the session):

/wEPZwUPOGNjMDFjZGYxNWZjYmViQpgJqyUrZohSJ3XG/uZnVdKp1Vk=

and the data transmitted on a simple postback to this:

Request Count:     1
Bytes Sent:     7,740
Bytes Received: 158,740

It yields a small but perceptible speed improvement on postbacks (the improvement is rather negligible on page changes though – when you switch from contact to account, for example).  One downside is it will require a bit more memory on the server side but even at an extra 600 kb per user (enough for 20 of the biggest viewstates) it is only a few hundred megs.

The steps were as follows:

  • Created a page adapter called “SessionViewStatePageAdapter” under the App_Code folder – see http://msdn.microsoft.com/en-us/library/system.web.ui.sessionpagestatepersister.aspx for the code, mine looks like this:
public class SessionViewStatePageAdapter : PageAdapter
{
    public override System.Web.UI.PageStatePersister GetStatePersister()
    {
        return new SessionPageStatePersister(this.Page);
    }
}
  • Add an “App_Browser” folder to the site (it shows up as an option in Visual Studio) and drop a file “Default.browser” with this content:
<browsers>
    <browser refID="Default">
      <controlAdapters>
        <adapter controlType="System.Web.UI.Page" adapterType="SessionViewStatePageAdapter"/>
      </controlAdapters>
    </browser>
</browsers>
  • Add this tag to the web.config (under system.web), otherwise only part of the ViewState will be affected:
<browserCaps>
      <case>RequiresControlStateInSession=true</case>
</browserCaps>
  • In this state the server will get confused if the user opens more than 9 windows (not including the “in-page” popups) so I increased that to 20 by adding this under system.web in web.config:
<sessionPageState historySize="20"/>

All in all a decent improvement for a minimal effort.

Comments
No Comments »
Categories
Programming, Saleslogix
Comments rss Comments rss
Trackback Trackback

Display user lookup as a dropdown (legacy-web style)

Nicolas Galler | September 1, 2009

Our users upgraded from 7.0 to 7.5 complained about the user lookup dialog – on 7.0 it used to be a dropdown, whereas on 7.5 it’s a popup similar to the LAN client.

image

Sorry for the chopped image, I had to hide the name and was too lazy to re-run on the eval db.

The problem is the popup takes a couple seconds to come up on IE7, sometimes more on slow machines or slow connections – it’s a bit irritating.  After a brief phase of denial (how dare they refuse the New and Improved way, etc) I set to work.  Had to struggle a bit with the combination of available properties but finally got it working.  Configuring lookup is definitely a big pain on the web client!  This is the winning combo:

  • Display Mode = DropDownList
  • Display Property = UserInfo.UserName
  • Lookup Entity Name = User
  • Lookup Binding Mode = Object
  • In the Lookup Pre Filters, add a filter on “Enabled” (make sure the property is populated as System.Boolean, and set OperatorCode to “=”) and filter value of “true”

The DropDown style lookups are a bit more picky on the parameters than the regular lookup, because they actually use NHibernate parameters instead of inline HQL.  In general I would say it is a good thing to use parameters, though in this case it makes it a bit harder for us to hack around the limitation of the control.

Data binding works fine, the only big problem I have found is that it sorts by first name instead of last name for some reason (which you can’t really see in the screen shot as I removed the last name but you can imagine).

Comments
1 Comment »
Categories
Uncategorized
Comments rss Comments rss
Trackback Trackback

Troubleshooting Reporting Server

Nicolas Galler | September 1, 2009

This post is an example of the tricks you can accomplish with Reflector as well as a reminder for me on how to do this.

If you have tried to set up a report server on the web client and run into any kind of trouble you may have noticed that there was very little diagnostic.  Yesterday I upgraded one of our customers from 7.2.2 to 7.5.1.  Most of it went smoothly (apart from some error in the downloaded installation files) but the reporting just would not work – Firefox just printed an obscure message “XML Parsing Error: no element found”, while Internet Explorer showed an empty page. 

image

Well actually they were both right – in lieu of a diagnostic message the report server page (SLXWebReportingServer.ashx) just did not return anything at all.  The first thing I did was make sure logging was enabled, and I edited log4net.config to make the name a bit more obvious (by default it just logs messages as “Service” – I changed it to “Saleslogix Web Reporting”).  Yet it still showed no message.  I had to get the report handler to print more diagnostic.  As it is a compiled assembly this cannot be done directly – however we can extract it using Reflector:

image

Paste the code in a file called SLXWebReportingServer.ashx in the slxwebrpt folder and add the handler directive at the top:

<% WebHandler language="C#" class="SLXWebReportingServer" %>

Then comment out the httpHandler directive in web.config and re-run the report (or you can just F5 the reporting window).  This will give a compilation error, of course, since we have not added any “using” directive.  Turn off customErrors in web.config (add a <customErrors mode=”off”/> under <system.web>) and add the missing using statements until you get the page to compile with the same error as the original one (there might be a way to get Reflector to generate the using statements, if so, i have not found it).  This is what I had to add for this one:

using System;
using System.Web;
using System.Web.SessionState;
using Interop.SLXWR;
using System.Runtime.InteropServices;
using log4net;
using Sage.SalesLogix.Reporting.Server;
using System.Data.OleDb;
using System.Data;
using System.Xml;
using System.IO;
using Sage.Platform;
using Sage.SalesLogix;

Create a logger object

public class SLXWebReportingServer: IHttpHandler, IRequiresSessionState
{
    private static readonly ILog LOG =
        LogManager.GetLogger(typeof(SLXWebReportingServer));

And verify that it works:

    public void ProcessRequest(HttpContext context)
    {
        try
        {
LOG.Warn("Boo");

OK, now we are ready to work.  The first thing I should have done at this point was add a log statement in the top-level catch block, at the very end of the file:

        catch (Exception exception2)
        {
LOG.Warn("Error in top level try/catch", exception2);
            context.Response.StatusCode = 500;
            context.Response.StatusDescription = exception2.Message;
        }

It’s a good idea to first scan for trapped, unlogged exceptions and make sure they are reported.  However, I smartly dove in and started peppering the code with LOG statements to get an idea of where it was hung:

    private static bool GetConnectionString(string userName, string password, string timeZoneKey, out string connectionString, out string dataSource, out string errorMsg)
    {
LOG.Info("GetConnectionString - 1");
        object obj2;
        connectionString = null;
        dataSource = null;
        errorMsg = null;
        string physicalApplicationPath = HttpContext.Current.Request.PhysicalApplicationPath;
        if (string.IsNullOrEmpty(physicalApplicationPath))
        {
            errorMsg = "ERR_APPLICATIONPATH";
            return false;
        }
LOG.Info("GetConnectionString - 2");
        string path = Path.Combine(physicalApplicationPath, "connection.config");
        if (!File.Exists(path))
        {
            errorMsg = "ERR_CONNECTIONCONFIG_NOTFOUND";
            return false;
        }
LOG.Info("GetConnectionString - 3");
        XmlDocument document = new XmlDocument();
        try
        {
            document.Load(path);
        }
        catch (Exception exception)
        {
            errorMsg = string.Format("ERR_CONNECTIONCONFIG_LOAD", exception.Message);
            return false;
        }
LOG.Info("GetConnectionString - 4");

You get the idea.  Eventually I found the GetRWPassword call was not returning and that’s when I realized there was a blanket catch statement.  From there the error was obvious (I had not installed the SQL native client on the report server) and of course the quick way to find out would have been to install the SalesLogix client on the box – but it was an interesting exercise nonetheless, and could prove useful in other cases.

To recap:

  1. First step should be to install the Sales client and make sure you can log in
  2. Then, edit the logging options to make sure you are looking for the correct messages
  3. If all fails, you can always replace the default handler to add some diagnostic
  4. Don’t forget to put the default handler back when done! :)

This is the ashx file I used (for version 7.5.1 – on other versions you’d have to make sure you get the appropriate code using Reflector).

Comments
1 Comment »
Categories
Uncategorized
Comments rss Comments rss
Trackback Trackback

« Previous Entries

Categories

  • Dojo (1)
  • Experiments (4)
  • Force.com (2)
  • Interesting (1)
  • Javascript (3)
  • MSCRM (1)
  • Programming (63)
  • Rant (3)
  • Saleslogix (41)
  • Tricks (8)
  • Uncategorized (32)

Post History

  • 2011
    • January (3)
    • February (2)
    • March (1)
  • 2010
    • January (3)
    • March (3)
    • April (2)
    • August (2)
    • October (4)
    • November (1)
    • December (2)
  • 2009
    • March (2)
    • April (1)
    • May (3)
    • June (3)
    • July (1)
    • September (3)
    • October (2)
    • December (5)
  • 2008
    • January (9)
    • February (4)
    • March (9)
    • April (1)
    • May (5)
    • June (8)
    • July (1)
    • August (2)
    • September (1)
    • November (1)
    • December (3)
  • 2007
    • January (3)
    • February (7)
    • March (1)
    • April (3)
    • May (6)
    • June (2)
    • July (1)
    • August (2)
    • September (5)
    • October (3)
    • November (5)
    • December (4)
  • 2006
    • January (2)
    • September (1)
    • November (3)
    • December (4)
  • 2005
    • April (1)

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox