1

I am working on a new page for a website at work, my boss would like it to have a friendly URL.

Currently website.com/account-payments.aspx and he wants it to be website.com/payments/

Problem is, I can't figure out how to rewrite the url properly. I've seen a NuGet package recommended "Microsoft ASP.NET Friendly URLs" but I don't have admin rights on this network and I can't install anything new. My boss is less than helpful regarding this.

Are there any built in features of ASP.net that will allow me to rewrite the url?

Edit

I have added this class to my App_Code folder.

Imports Microsoft.VisualBasic
Imports System.Web

Public Class PaymentsHandler

    Implements IHttpHandler

    Public Sub ProcessRequest(ByVal context As  _
            System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest

        If context.Request.RawUrl.EndsWith("/payments/") Then
            context.Server.TransferRequest("/account-payments.aspx")
        End If
    End Sub
    Public ReadOnly Property IsReusable As Boolean Implements System.Web.IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
End Class

With the following handler in my web.config file:

<handlers>
<add name="Payments" verb="*" path="/payments" type="PaymentsHandler" resourceType="Unspecified" />
</handlers>

And now, instead of a generic 404 error, I get the 500 internal server error when attempting to browse to website.com/payments/

Edit 2: Electric Boogaloo

So after Googlin about I found someone having a similar problem and they fixed theirs by adding an extra handler to the web.config.

<httpHandlers> <add verb="*" path="*/account-payments.aspx" type="PaymentsHandler" validate="false"/> </httphandlers>

I checked my webconfig and sure enough there are existing handlers in both <handlers> and <httpHandlers>

Now, instead of the old 500 error, I'm getting a 403 error. Getting real confused.

Edit 3: The Editing

Progress! I switched from HTTPHandler to HTTPModule and rigged up my PaymentsHandler.vb to match:

Public Class PaymentsHandler

    Implements IHttpModule

    Public Sub Init(context As HttpApplication) Implements System.Web.IHttpModule.Init

        AddHandler context.BeginRequest, New EventHandler(AddressOf context_BeginRequest)
        AddHandler context.EndRequest, New EventHandler(AddressOf context_EndRequest)
        AddHandler context.AuthorizeRequest, New EventHandler(AddressOf context_AuthorizeRequest)

    End Sub

    Private Sub context_AuthorizeRequest(sender As Object, e As EventArgs)
        'We change uri for invoking correct handler
        Dim context As HttpContext = DirectCast(sender, HttpApplication).Context

        If context.Request.RawUrl.Contains("account-payments.aspx") Then
            Dim url As String = context.Request.RawUrl.Replace("account-payments.aspx", "payments")
            context.RewritePath(url)
        End If
    End Sub

    Private Sub context_EndRequest(sender As Object, e As EventArgs)
        'We processed the request
    End Sub

    Private Sub context_BeginRequest(sender As Object, e As EventArgs)
        'We received a request, so we save the original URL here
        Dim context As HttpContext = DirectCast(sender, HttpApplication).Context

        If context.Request.RawUrl.Contains("account-payments.aspx") Then
            context.Items("originalUrl") = context.Request.RawUrl
        End If
    End Sub

    Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

    End Sub

Now I can see that the rewrite is happening! Yay! So when I browse to website/account-payments.aspx it automagics to website/payments/ and then I get a 403 - Forbidden error.

So it's rewriting, and redirecting... but apparently the page is now forbidden?

Wompguinea
  • 378
  • 3
  • 19
  • You should be browsing to `website/payments` and it redirecting to `website/account-payments.aspx`. You need to switch these round in your code. The 403 is because it thinks you want to view the `payments` directory and listing the contents is not allowed. – Dave Anderson Sep 01 '15 at 23:29
  • I tried it with two existing pages with .aspx extensions, and you're right. However, as soon as I change it back to the extentionless `/payments` page I get the 403 error again. Is it just not going to work without the .aspx extension? – Wompguinea Sep 01 '15 at 23:48
  • Did you change the web.config for the `path=` as well? Try using just `path="*"` this should send any request through your handler. Normally you try and limit the request to just those you expect to have to handle i.e. `path="/payments`. – Dave Anderson Sep 02 '15 at 00:06
  • Was there are reason you switch from Server.Transfer to RedirectPath? See http://stackoverflow.com/questions/1757336 – Dave Anderson Sep 02 '15 at 00:21
  • I read [this article](http://www.codeproject.com/Articles/335968/Implementing-HTTPHandler-and-HTTPModule-in-ASP-NET) which advised against an httphandler and said to use an httpmodule instead. It doens't seem to specify a path? Also, that's where the RedirectPath code came from. – Wompguinea Sep 02 '15 at 00:40

2 Answers2

1

You can write your own HttpHandler that you can wire up in the web.config. This class can check the HttpRequest url and map that to your aspx page.

C#

public class PaymentsHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.Request.RawUrl.EndsWith("/payments/"))
        {
            context.Server.TransferRequest("account-payments.aspx");
        }
    }
}

VB

Public Class PaymentsHandler
    Implements IHttpHandler
    Public Sub ProcessRequest(context As HttpContext)
        If context.Request.RawUrl.EndsWith("/payments/") Then
            context.Server.TransferRequest("account-payments.aspx")
        End If
    End Sub
End Class

Obviously the logic to map the requests needs to be sufficiently robust. You add it to the web.config like this;

<system.webServer>
    <handlers>
      <add name="Payments" verb="*" path="/payments" type="PaymentsHandler" resourceType="Unspecified" />
    </handlers>
</system.webServer>

See;

Dave Anderson
  • 11,836
  • 3
  • 58
  • 79
  • BTW you don't have to map all requests, just handle the ones you need custom logic for. The other request are passed down the request chain until they are fully handled. – Dave Anderson Sep 01 '15 at 03:52
  • Sorry, I'm not very bright. Do I create that class as a separate class file or cram it into one of my existing .aspx files? – Wompguinea Sep 01 '15 at 04:00
  • 1
    I would create a file `PaymentsHandler.cs` for the class and put it in the `App_Code` directory. If your project uses a namespace I would add that to the file and then the `web.config` would need to include `type="project.namespace.PaymentsHandler"` where you have your projects namespace before the class name. – Dave Anderson Sep 01 '15 at 04:19
  • I'm now getting a `500 - Internal Server Error` which I assume is a step-up over the old 404 I was getting before. I'm working in VB.net if that makes a difference? – Wompguinea Sep 01 '15 at 04:36
  • Can you update your post with the 500 error? Can you start a debug session so you can step into the code? – Dave Anderson Sep 01 '15 at 04:46
  • Code added but debug's a no go, for some reason the way this site is hosted on the server causes the debug to never load correctly. I have to update code then refresh the site in Chrome to see if my changes work. – Wompguinea Sep 01 '15 at 04:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/88437/discussion-between-dave-anderson-and-chris-hinton). – Dave Anderson Sep 01 '15 at 04:52
1

You could try this

   void Application_BeginRequest(object sender, EventArgs e) {

    string fullOrigionalpath = Request.Url.ToString();

    if (fullOrigionalpath.Contains("/account-payments.aspx")) {
        Context.RewritePath("/payments.aspx");
    }
} 

I recommend you read this blog for other methods

Rachel Gallen
  • 27,943
  • 21
  • 72
  • 81
  • Thanks for the suggestion, I think I kind of have that in my httpmodule now and things are working better than before but it's still not loading the page properly? – Wompguinea Sep 01 '15 at 23:05
  • does it take a long time or does it just not load. what do you mean by not properly? – Rachel Gallen Sep 01 '15 at 23:07
  • It changes the url in the browser almost instantly, and then just loads a generic 403-forbidden error? – Wompguinea Sep 01 '15 at 23:08
  • that sounds like an administrative rights issue to me. Maybe only some people can do a rewrite. Is this a personal thing or a company thing? – Rachel Gallen Sep 01 '15 at 23:10
  • It's a company thing. I have full access to all the source code of the site, but almost no rights on the company servers. Is this likely to be the problem? – Wompguinea Sep 01 '15 at 23:11
  • do you have access to the xml? if you read the blog there's an alternative route. by adjusting the xml and you can set require permissisons to false – Rachel Gallen Sep 01 '15 at 23:14
  • leave the code in there as is to be sure to be sure though. – Rachel Gallen Sep 01 '15 at 23:14
  • download https://github.com/sethyates/urlrewriter in order to make the xml changes.- free – Rachel Gallen Sep 01 '15 at 23:17