Tuesday, December 19, 2006

ASP.Net unhandled exception logging

Here is a snippet of code that can be added to your Global.asax file that will log all errors that are not handled in your ASP.Net application. The results in this example are logged to a separate log called “FrontLine Web App” (other options would be Application or System or whatever your custom name is) and the source for the entries in that log are logged as “FrontLine Web App” as well.

void Application_Error(object sender, EventArgs e)

{

// Code that runs when an unhandled error occurs

Exception objErr = Server.GetLastError().GetBaseException();

string logName = "FrontLine Web App";

if (!EventLog.SourceExists(logName))

{

// Note: we are writing to a special FrontLine Web App log

//(specified in second param)

EventLog.CreateEventSource(logName, logName);

}

EventLog log = new EventLog();

log.Source = logName;

// write the error to the Event Log

string err = "Error Caught in Application_Error event\n" +

"Error in: " + Request.Url.ToString() +

"\nError Message:" + objErr.Message.ToString() +

"\nStack Trace:" + objErr.StackTrace.ToString();

log.WriteEntry(err, EventLogEntryType.Error);

}

Also, you will probably want to include the following line in your web config so that end users won’t see the actual unhandled exception, it will just show a custom error page.

<customErrors mode="On" defaultRedirect="FriendlyErrorPage.aspx" />

Friday, December 15, 2006

Best Comparison Tool Around

I have been using Beyond Compare 2 for a two or three of years now. It is the best $30 you will ever spend for computer software if you work with files on a daily basis. I can’t say enough good things about it. It allows you two compare and merge files and directories on local, UNC paths, and even ftp. You can specify exactly how you want to treat orphans, differences in files, exclude files, etc. You can even define rules as to how the content of files should be treated. For example, is white space important. The easiest way to compare two files is to right click the two files you want to compare, and it will open up Beyond Compare 2. You can even script everything with its very easy syntax. I use it for backing up my files to a backup share every night. It supports copying and synchronizing. You can do so from left to right, right to left, both directions. It is truly a powerful and easy to use interface for synchronizing changes at the file and directory level. If you work for a company that needs bulk licensing, unlimited, or global licensing they have extremely nice pricing for bulk customers.

Thursday, December 14, 2006

Inserting value into identity column

When moving data from one database instance to another in SQL Server 2000 or SQL Server 2005 you can create insert statements to do this. The problem comes when you try to keep relationships between tables or even just keep identity columns on one table the same as the source.

Let’s assume you have only one table to move and it is defined as follows:

CREATE TABLE [CustomerCategory](

[CustomerCategoryID] [int] IDENTITY(1,1) NOT NULL,

[Name] [nvarchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,

[Code] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,

[RegionID] int NOT NULL

) ON [PRIMARY]

Assume the tabe can be scripted as follows and has two rows:

INSERT INTO CustomerCategory (CustomerCategoryID, [Name], Code, RegionID)

VALUES (45, 'Computer', 'COMPUTER', 1)

INSERT INTO CustomerCategory (CustomerCategoryID, [Name], Code, RegionID)

VALUES (46, 'Printer', 'PRINTER', 1)

Notice that the CustomerCategoryID is an identity column and therefore SQL Server won’t let you do the above.

To get around this you need to use the SQL Server specific option IDENTITY_INSERT

Here is the final solution for inserting the data into the new table and keeping the identity column values in tact.

set IDENTITY_INSERT CustomerCategory ON

INSERT INTO CustomerCategory (CustomerCategoryID, [Name], Code, RegionID)

VALUES (1, 'Computer', 'COMPUTER', 1)

INSERT INTO CustomerCategory (CustomerCategoryID, [Name], Code, RegionID)

VALUES (2, 'Printer', 'PRINTER', 1)

set IDENTITY_INSERT CustomerCategory OFF

This type of thing comes in handy when moving database tables from dev to QA or QA to Production.

Tuesday, December 12, 2006

Web.xml to configure your Java Web Service

This blog describes how to configure your Java Web Service. Specifically, how to initialize your Java Web Service. In this article I assume you have used Sun Java Studio Enterprise 8 to create your RPC based web service.

Add the following lines to the top of you web service class. Typically this class ends in Impl. Your web service class needs to implement ServiceLifecycle. The example below shows how to read the init param called MyParam that is in web.xml.


import javax.xml.rpc.server.*;
import javax.xml.rpc.*;

public class MyDemoWSImpl implements MyDemoWSSEI, ServiceLifecycle {

     // store the servletContext here since we can only get it when the applet starts up.
     private ServletContext servletContext;


     // Required by ServiceLifecycle interface
     // This is only called once when the web service is started.
     // This is NOT called everytime a web method is called
     public void init(Object context) throws ServiceException
     {
          // get the servlet context
          // This is where the General context parameters (aka init parameters) of the web.xml are stored.
          ServletEndpointContext soapContext = (ServletEndpointContext) context;
          servletContext = soapContext.getServletContext();
     }


     // Required by ServiceLifecycle interface
     public void destroy()
     {
    
     }

     public String MyParam() throws Exception
     {
          return GetInitParam("MyParam");
     }


}

 

To add and specify the value for MyParam in web.xml you need to find you web.wml file. It is typically in the Web Pages\Web-INF\web.xml path if you are using BluePrints type project in Sun Java Studio Enterprise 8. You can type the entry in web.xml as shown below or you can just double click the web.xml file and use the Sun Java Studio Enterprise 8 editor. The editor has tabs. Click on the General tab if it is not already selected. Expand the Context Parameters section, then click the Add button. Type in MyParam as the Param Name, some value as Param Value, and Description is a description of what the param is or what it is for (whatever you want to put there, it is just for documentation purposes).

Here is web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <context-param>
    <description>MyParam description for documentation</description>
    <param-name>MyParam</param-name>
    <param-value>the value of MyParam</param-value>
  </context-param>
  <servlet>
    <servlet-name>WSServlet_MyDemoWS</servlet-name>
    <servlet-class>philips.MyDemoWSImpl</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>WSServlet_MyDemoWS</servlet-name>
    <url-pattern>/MyDemoWS</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>
            30
        </session-timeout>
  </session-config>
  <welcome-file-list>
    <welcome-file>
            index.jsp
        </welcome-file>
  </welcome-file-list>
</web-app>

Tuesday, December 5, 2006

Restoring SharePoint Portal Server 2003

OK, so you have a backup plan for SharePoint that uses the spsbackup which is the Backup and Restore application in the Start Menu that comes with SharePoint Portal Server 2003 (SPS). The question now what needs to be done if the server goes down. Well, that fully depends on what size farm you have configured SharePoint to use. For simplicity we will assume you have just one server and everything is running on. Let's also assume that we have configured SharePoint as a Server Farm installation. This allows us to use SQL Server 2000 instead of MSDE. Here is a summary of the environment I am assuming in this example:
  • SQL Server 2000 SP4
  • IIS 6 with ASP.Net 1.1 installed only (no ASP.Net 2.0 as it doesn't work with SharePoint prior to SharePoint Portal Server 2003 Service Pack 2). You should be able to install ASP.Net 2.0, but your Search for SPS won't work until you patch SPS to SP2.
  • SharePoint Portal Server 2003 (SPS)
  • Windows SharePoint Services (WSS)
  • SharePoint Portal Server 2003 Service Pack 2 (SPS-SP2)
  • Windows SharePoint Services Service Pack 2 (WSS-SP2).
The short answer is you need a machine that has the same programs, service packs, versions, etc. Then restore everything via spsbackup. Here is a little more detail:
  1. Install SQL Server 2000
  2. Install SQL Server Service Pack 3 or above. Ideally, this should match whatever you are using on the production server for SharePoint, though it is not required in most cases.
  3. Install IIS and ASP.Net. I recommend using the Mnage Server app to install them. It is quick and painless. Just select the IIS and ASP.Net role.
  4. Reapply Windows Server 2003 Service Pack so that IIS will be patched also.
  5. Install SharePoint Portal Server 2003.
  6. Install Windows SharePointPortal Server.
  7. Install Service Pack 2 for SharePoint Portal Server 2003. NOTE: Service Packs may overwrite customizations.
  8. Install Service Pack 2 for Windows SharePoint Services.
  9. Install any templates, sites definitions, configuration file changes, customizations, etc.
  10. At this point the backup server and the production server should have identical environments. At this point, you can create a new portal if you haven't already and verify that SharePoint Portal Server 2003 and at least one WSS site works ok.
  11. Run spsbackup and restore SharePoint.
  12. Testing restore. You will probably note that SPS search doesn't work as expected, and that Sites directory in SPS still point to old server. This is not an issue in a real emergency restore situation where the url will not change, but if you use these steps to restore to a test server for example you need to make some changes. The simplist solution appears to be to do a search and replace in the databases for SharePoint ( 4 of them, but not all have references to url). I recommend this stored procedure that can be added to each of the databases and used to search and replace url. There is also a search only (no replace) that you can use to just see what changes will be made if you do the search and replace. One bit of warning, I read that some data is not stored in plain text and is blob, etc columns which this procedure does not operate on. I have not seen this, I just read about someone having an issue. Please let me know if you notice an issue.
  13. Upgrade SQL Server 2000 to SQL Server 2005. This step makes upgrading to SQL Server 2005 easiest since there is no backup and restore. This step is optional and should only be done if you want to use SQL Server 2005 as your database AND do not want to have a separate instance of SQL Server 2000 still running. If you want to have both SQL 2000 and SQL 2005 on the same machine, you will need to backup and restore to SQL 2005. There have been some other people reporting that spsbackup doesn't work with SQL Server 2005. This is true I think only if you do NOT have SPS-SP2. Without SPS, SQL Server 2005 is not supported.
  14. Do a backup using spsbackup. You existing (pre-SPS-SP2) backups will no longer be able to be restored using SPS-SP2 spsbackup. So, you will probably want to get a new backup.