Sunday, July 29, 2012

Proper error handling in ASP.NET Web Forms


I want to show users two custom pages:
1) Error500.aspx -- for uncaught exceptions.
2) Error404.aspx -- for non-existing page.

The trick is that ASP.NET handles requests to *.aspx pages differently than to other types of pages.

Here's how I do it.

In Web.Config:

<system.web>
        <customErrors mode="RemoteOnly" defaultRedirect="~/Error.aspx" redirectMode="ResponseRewrite">
               <error statusCode="404" redirect="~/Error404.aspx"/>
               <error statusCode="500" redirect="~/Error500.aspx"/>
        customErrors>
system.web>

<system.webServer>
        <modules runAllManagedModulesForAllRequests="true">
               <add name=" PostJobFreeModule" type="PostJobFree.PostJobFreeModule" preCondition="managedHandler"/>
        modules>
        <httpErrors existingResponse="PassThrough" />
system.webServer>

In PostJobFreeModule.cs I use:
void application_EndRequest(object sender, EventArgs e)
{
        PageNotFoundHelper.ShowError404IfNeeded();
}

public static class PageNotFoundHelper
{
        public static void Set404StatusCode()
        {
                HttpContext.Current.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
               HttpContext.Current.Items["Set404StatusCode"] = true;
        }
 
        public static void ShowError404IfNeeded()
        {
               if (!HttpContext.Current.IsCustomErrorEnabled) return;
               if (HttpContext.Current.Response.StatusCode == 404)
               {
                       if (HttpContext.Current.Items["Set404StatusCode"] == null)
                       {
                               HttpContext.Current.Server.Transfer("~/Error404.aspx");
                       }
               }
        }
}

Thursday, July 26, 2012

Drop orphaned user who holds SQL Server service

It's easy to google "The database principal owns a schema in the database, and cannot be dropped" error, but have you tried to google "The database principal owns a service in the database, and cannot be dropped."?

I tried, and the results were miserable -- I could find only half-baked solutions.
In my case I restored SQL Server backup database that had service broker turned on and then tried to drop orphaned user... unsuccessfully as you can guess.

Here's the solution.

1) Run this query:
select
 'alter authorization on service::[' + name + '] to dbo;' as [SQL to execute prior to dropping user]
from sys.services
where principal_id = user_id('MyServer\MyOrphanedUser');
2) Execute SQL that you get as a result of the query above. It would look something like that:
alter authorization on service::[SqlQueryNotificationService-25509d9f-4171-4701-817f-834f79a4a882] to dbo;

3) Finally you can drop your orphaned user:
drop user [MyServer\MyOrphanedUser];

Credits: How to disconnect service from orphaned user by Nimit Parikh

P.S.: I also tried:
delete from sys.services where principal_id = user_id('MyServer\MyOrphanedUser')
and got: "Ad hoc updates to system catalogs are not allowed." error.

Followers

About Me

My photo
Email me: blog@postjobfree.com