Best practice for SharePoint vanity url/redirection - sharepoint

My employer uses MOSS 2007 for our company intranet. It runs solely on secure http and is also exposed to the outside world via ISA. I currently have a request to add a forwarding URL to our site so that something like the following will occur:
intranet.mycompany.com/vanityname
redirects to ->
intranet.mycompany.com/somedeeplink/default.aspx
I fully expect this sort of thing will become more popular with our users as time goes on. So I am looking for a solution that scales. I have read various articles about creating a /site/ with forwarding meta tags or a forwarding SharePoint page type. I've also seen some that talk about adding virtual directories, etc directly in IIS. All these solutions seem to be overkill and inevitably take up more memory or processing time on the web servers.
I am currently leaning towards writing an http module that can be configured in the web.config and perform redirects. I wanted to get feedback to see if anyone else has done something similar in SharePoint 2007 and had any suggestions. Again, I'd like to implement something that scales without making major changes later on and is going to put minimal processing burden on our web servers. Thanks!

Ive implemented url redirecting with MOSS using the HTTP module route. I documented the code I used and what parameters worked the best for me here;
http://scaredpanda.com/2008/08/url-rewriting-with-sharepoint-moss-2007/
Take a look and let me know if this helps you and if you have any questions.
Update: The link above is no longer valid, so here text from the page that I used for URL redirect.
After messing around for a little bit it, I came up with a good way to do it. When I was looking for examples on the web there were a lot of people saying that it couldnt be done. But in the end it actually didn’t take much to implement it. Here’s an HttpModule that I wrote to do the work.
The key pieces are the this.app.BeginRequest += new EventHandler(app_BeginRequest) which
steps in front of the request and allows the module to get its redirect on.
And HttpContext.Current.RewritePath(redirect, false); will push the necessary headers n such forward so that the receiving .aspx page will understand how to correctly post back.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Collections;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Web.SessionState;
using System.Security.Cryptography;
using System.Configuration;
using System.Threading;
using System.IO;
using System.Security;
using System.Security.Principal;
namespace ScaredPanda
{
public sealed class RewriteHttpModule : IHttpModule
{
HttpApplication app = null;
///
/// Initializes the httpmodule
///
public void Init(HttpApplication httpapp)
{
this.app = httpapp;
this.app.BeginRequest += new EventHandler(app_BeginRequest);
}
public void app_BeginRequest(Object s, EventArgs e)
{
try
{
//determine if the income request is a url that we wish to rewrite.
//in this case we are looking for an extension-less request
string url = HttpContext.Current.Request.RawUrl.Trim();
if (url != string.Empty
&& url != "/"
&& !url.EndsWith("/pages")
&& !url.Contains(".aspx")
&& url.IndexOf("/", 1) == -1)
{
//this will build out the the new url that the user is redirected
//to ie pandas.aspx?pandaID=123
string redirect = ReturnRedirectUrl(url.Replace("/", ""));
//if you do a HttpContext.Current.RewritePath without the 'false' parameter,
//the receiving sharepoint page will not handle post backs correctly
//this is extremely useful in situations where users/admins will be doing a
//'site actions' event
HttpContext.Current.RewritePath(redirect, false);
}
}
catch (Exception ex)
{
//rubbish
}
}
}
}

Have you looked into Alternate Access Mappings?
http://technet.microsoft.com/en-us/library/cc263208.aspx

If you are open to paying for a solution. Have a look:
NOT FREE -> http://www.muhimbi.com/Products/SharePoint-URL-Shortener.aspx

Depending on the number of redirects you might want to implement an HTTP module as stated) but how about checking out
FREE -> http://www.codeplex.com/sharepointsmart404

Use the URL Rewrite feature in IIS. (I believe it's an IIS 7 extension)
http://www.iis.net/download/urlrewrite

Related

webview whitelist urls possibly from external file

We have locked down tablets deployed that are going to be using a webview based app that will allow our users to interact with our web app, website, and a few other whitelisted URL's like social media pages.
I know I can easily accept a single URL and reject all others with something like this:
public class MyWebViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading (WebView view, String url) {
if (Uri.parse(url).getHost().equals("http://Your_website_url")) {
// This is my web site, so do not override; let my WebView load the page
return false;
}
// reject anything other
return true;
}
}
mWebview.setWebViewClient(new MyWebViewClient()); //set the webviewClient
I could possibly adapt this to allow for multiple URL's but it seems somewhat messy and cumbersome. Ideally, I think an external XML file that can be updated without the app needing to be redeployed to all devices may be the way to go, I am a little unsure how to make that happen though and no one seems to have done this before that I can find.
I am fairly new to this so any help would be greatly appreciated.
Have your tablets reach back to a server for updated permission lists. You can look at Spring Cloud Config Server as a real-world example.

Using hooks to trigger a process

I am trying to work out how to use the Hooks and just can't seem to get the syntax correct.
I have built a site using PirahnaCMS that has a blog component and am extending it to call some social plugins and auto post to FB, Twitter etc.
I just can't seem to get the syntax correct though. My app is MVC and I have looked at this section
1.2 ASP.NET MVC
If you're using ASP.NET MVC hooks should be attached in you Global.asax.cs in the Application_Start method, or any other place where you keep you startup code. You attach you hooks with the followin syntax:
protected void Application_Start() {
Piranha.WebPages.Hooks.Menu.RenderItemLink = (ui, str, title, url) => {
str.Append(String.Format("<span>{1}</span>", url, title)) ;
} ;
}
The Hook I believe I want to use is Piranha.WebPages.Hooks.Manager.PostEditModelAfterSave but for the life of me I can't seem to work it out.
All of the hooks are just static delegates that you can attach methods to. In the above example an anonymous method has been assigned to the hook with the syntax:
delegate += (parameters) => { method body }
You could also assign a previously declared method.
delegate += MyMethod
Example skeletons for attaching hooks should be available in the Docs at the official site. If not you can find the hooks in the file:
~/WebPages/Hooks.cs
And all delegates in:
~/Delegates.cs
I hope these URL:s are correct as I'm typing from memory :)
Regards

Problem opening context SPSite from SPItemEventProperties

In the following code,
// class overrides SPItemEventreceiver
public override void ItemAdding(SPItemEventProperties properties)
{
using (var site = new SPSite(properties.SiteId)) //SiteId is GUID <<corrected
{
...
}
}
The following exception is thrown:
System.IO.FileNotFoundException: The Web application at http://URL could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.
One way to work around this is to hard-code (or configure) the URL specified in Alternate Access Mappings. Putting the correct URL in Alternate Access Mappings is ultimately the correct solution, but if possible, I need a work-around that doesn't require configuration.
SiteId should not be an integer - SPSite ctor only accepts URLs or Guids. Given that it is an GUID, I don't see how AAM plays a part here. An alternate approach might be to use:
properties.OpenWeb().Site
Also, since you are in a synchronous event handler you should have access to SPContext.Current.Site (unless you're trapping events in a document library - a long standing sharepoint bug means there is no context in sync events for doclibs - shitty)
-Oisin

How to use ASP.NET Session State in an HttpHandler?

I have an HttpHandler that is run on a client page (cross domain, not on our IIS server, etc) and when they click on our embedded link it fires off the Handler on our server. So far everything is working normally.
I am now trying to use the System.Web.HttpContext.Session object but it is null. I am thinking it is null because we don't have a session until our HttpHandler is invoked? And multiple calls to the handler will create a new session per call? If this is the case did MS just disable the Session object when calling into a HttpHandler? Can anyone confirm this?
If this is the case, what do you do to maintain state between calls? Some sort of SQL based data object? A file?
TIA
Have your HttpHandler implement the IRequiresSessionState interface. It will enable session state use.
IRequiresSessionState can be found in the System.Web.SessionState namespace.
I think you have to implement the empty interface IReadOnlySessionState, so the context will be loaded.
edit to add:
According to Michael Morton's answer, you can also implement IRequiresSessionState, which will give you write access also to the Session object
using System;
using System.Web;
using System.Web.SessionState;
public class DownloadHandler : IHttpHandler, IReadOnlySessionState
{
public bool IsReusable { get { return true; } }
public void ProcessRequest(HttpContext context)
{
context.Response.Write(context.Session["kmx"]);
}
}
try using the current context...
System.Web.HttpContext.Current.Session

Support for Long Running Operations using the MOSS Publishing Infrastructure

I have used the Long Running Operation capability within the Publishing Infrastructure within MOSS (SharePoint) in the past, and am curious if anyone knows if this is a supported technique for having custom long running operations within SharePoint.
When using this technique, you inherit from Microsoft.SharePoint.Publishing.Internal.LongRunningOperationJob which seems to indicate that it is not supported for custom use, but I seem to recall (maybe I dreamt?) that long running processes was a marketed feature of MOSS.
Any ideas?
SharePoint Timer Jobs are described in MSDN Journal April edition
http://msdn.microsoft.com/en-us/magazine/dd569748.aspx
Good question Kirk! I have recently also experienced the need to implement long running jobs in SharePoint. But the LongRunningOperationJob was not an option as it also needed to work with a plain WSS 3.0 deployment. I simply ended up spawning a new thread from the Web request and redirecting to an ASPX page with an AJAX enabled progress bar updating itself every other second. It works perfectly well and can run as long as needed. Only downside is that an IISRESET will kill it for good. Another possibility could be to implement long running jobs using a custom SharePoint Timer Job.
SPLongOperation is a very simple way to do a long running operation. Much simpler than the Publishing.LongRunningOperationJob and uses the same infrastructure.
Ever woundered how microsoft create the nice longrunning process windows works in SharePoint 2007?
SPLongOperation is the class to use. It has 2 important methods
Begin and End;
All your code that runs for a long time is placed between begin and end.
Below is a sample class.
It is almost to simple and just works :-)
using System;
using System.Web;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
namespace CreateLongOperation
{
public class LongRun : System.Web.UI.Page
{
protected Button buttonOk;
protected void Page_Load(object sender, EventArgs e)
{
buttonOk.Click += new EventHandler(buttonOk_Click);
}
void buttonOk_Click(object sender, EventArgs e)
{
SPLongOperation operation = new SPLongOperation(this.Page);
operation.Begin();
// do long operation code here...
System.Threading.Thread.Sleep(6000);
operation.End("http://sps/_layouts/Mynewpage.aspx");
}
}
}

Resources