views:

397

answers:

2

We have a set of code that is going to be used in both standalone ASP.NET and SharePoint. I'm wondering if there's any legitimate way to write conditional code in the CS file to detect whether SharePoint is present?

It needs to be able to run in or before OnPreInit, because based on this decision we'll be switching the MasterPageFile attribute, and that needs to be done early in the page lifecycle.

I suppose I can do something like checking for the existence of a "~/layouts" directory, etc. but there must be a better way to do this. And besides, who knows - for compatibility reasons (location of images, etc) we might actually adopt the SharePoint directory structure in the ASP.NET standalone mode.

It's okay to require the Microsoft.SharePoint.DLL even if it goes mostly unused when running standalone.

Thanks!

+7  A: 

Since you are allowed to reference Microsoft.SharePoint:

using Microsoft.SharePoint;
// ...

if (SPContext.Current == null)
    // Not running in SharePoint
else
    // Running in SharePoint

Edit -- alternate approach taking NullReferenceException into consideration:

bool runningInSharePoint = false;
try
{
    if (SPContext.Current != null)
        runningInSharePoint = true;
}
catch (NullReferenceException e)
{
    // SharePoint is not present on the system
}

The above assumes that the exception you mentioned is thrown when accessing SPContext, not earlier.

Johnny G
Unfortunately, I tried this out, and it crashes on a machine that doesn't actually have SharePoint installed. It's okay for me to reference the DLL but it needs to work when SP itself is not present.
Steve Eisner
Here's the stack trace for those who are curious - [NullReferenceException: Object reference not set to an instance of an object.] Microsoft.SharePoint.Utilities.SPUtility.AlternateServerUrlFromHttpRequestUrl(Uri url) +27 Microsoft.SharePoint.Administration.SPAlternateUrl.get_ContextUri() +135 Microsoft.SharePoint.WebControls.SPControl.SPWebEnsureSPControl(HttpContext context) +237 Microsoft.SharePoint.WebControls.SPControl.GetContextWeb(HttpContext context) +25 Microsoft.SharePoint.SPContext.get_Current() +107
Steve Eisner
If the exception you mentioned is thrown when you access SPContext.Current, then my 2nd approach above might work for you. Nat's solution below is better from an architectural point of view, though.
Johnny G
Thanks. Your edit is what I had implemented after I found the first version was crashing. It works, and because this is a one-time statically initialized variable the Exception-catching isn't a pain or perf hit. I'm still hoping there's some legitimate way to check for SharePoint....
Steve Eisner
+2  A: 

I wonder if you are better off not including the SharePoint dll in your straight ASP.NET code. If you partial/sub class the SharePoint bit and include two build targets, you should be able to tack on the extra code needed for SharePoint without turding up your ASP.NET build.

Nat
Thanks Nat, and I understand your point. I think it's a pretty clever idea to make a partial class and pair it with two different implementations. But it's difficult enough to divide my classes that I'm not sure it'll be worth the effort up front. I suspect what we'll do is use the if (IsSharePoint) { .. } else {..} logic for a while and then later, revisit to figure out where to split the class up as you suggested.
Steve Eisner