Question: I have an intranet application that needs contact information for various locations on our campus that are served by our IT lab support organization. We have an enterprise directory that contains contact information so I'm not keeping the actual contact information in the database, but rather an immutable identifier that serves as a key to look the person up in our enterprise directory (via a web service). I'll be looking contact information up via a publicly available web site.

The problem comes in that the id that is useful to the web-based directory lookup is only "sort of" immutable and is not the id that I will store in the database. Directory lookups are most easily performed using the person's Active Directory login id. What I will be using is called the Master Records Unique ID.

My question is: where is the most reasonable place to do the translation from MRUID to Active Directory login id for the link?

Right now I'm doing the translation in the presentation layer, with application-level caching to reduce look ups to the directory. Currently there is only a single web site, but I would expect that if there are other web sites that need to do this, I would migrate the helper class to a shared web controls library.

I considered putting the code in the data or business layer, but opted not to because of the caching. How and what you cache seems to be more a function of the application rather than these other layers.

I'd be interested in other opinions and ideas that I may not have considered.

Answer: 
When faced with something that needs to be in the presentation layer of an asp.net web site or web application, but it also may have value in other asp.net web applications I find it useful to create a special class library that has a dependency on the system.web namespace.

Specifically, it will make use of HttpContext.Current to interoperate with the web site that is hosting the library. I'm not sure, but I generally think of this as a business layer assembly, but one that assumes it is hosted in a web context. 

I keep my true business code (code that might be used in a non-web application) in a third assembly.

Having an assembly that depends on the web context allows you to use HttpContext.Current to find out what is going on with request and response objects as well as allowing you to interact with the asp.net cache API and related stuff. But it also keeps the code portable for use in more than one web application too.

Generally this web-dependent assembly is also where my HttpModules and HttpHandlers live too. 

Keep in mind though that "layers" are logical concepts, not physical ones. There is nothing wrong with an assembly that contains business, DAL, and even presentation layer classes together. The classes themselves shouldn't mix up their roles, but a single assembly can contain classes from different logical layer in your design.
You could place it in your business layer and still use caching, either using the Enterprise Library [Caching Application Block](http://msdn.microsoft.com/en-us/library/cc309502.aspx) in the business layer, or by caching the value returned by the business layer in the ASP.Net cache in your presentation layer.

As it's coming from a different location to your other data I wouldn't put it in the same data access layer as the other database code.