How to use ASP.NET 2.0 Profile object from web service code
You have started to use ASP.NET 2.0 Profile Provider and you are
very happy with it. All your .aspx pages are full of
"Profile.Something". You also introduced a lot of new properties on
the profile object via web.config. Then you added a new web
service. There you want to access the Profile object. You realize,
you are doomed.
You cannot access the Profile object from Web Service.
At runtime, ASP.NET generates a class looking at the
specification provided in web.config, which becomes the "Profile"
object in .aspx pages. But this object is not available in Web
service (.asmx.cs) and you cannot see the custom properties you
have added in the profile object. Although
HttpContext.Current.Profile will give you reference to Profile
object, but it's type is ProfileBase which does not show your
custom properties. Makes sense, because the class is generated at
runtime. But if it can be made available in .aspx.cs, then it
should also be available in .asmx.cs.
In order to overcome this problem, you have to hand code that
profile class in your App_Code folder and then configure web.config
so that it does not auto generate the class instead use your one.
Here's what you do in web.config:
<profile enabled="true"
inherits="UserProfile">
I have added a new attribute UserProfile. Now go to App_Code and
make a UserProfile class like this:
public class UserProfile :
System.Web.Profile.ProfileBase
{
[SettingsAllowAnonymousAttribute(true)]
public virtual int Timezone
{
get
{
return ((int)(this.GetPropertyValue("Timezone")));
}
set
{
this.SetPropertyValue("Timezone", value);
}
}
Declare all the properties like this. Don't forget to add the
[SettingsAllowAnonymousAttribute(true)] on the properties which you
want to be made available to anonymous users.
At the end of the class, add this method:
public virtual ProfileCommon
GetProfile(string username)
{
return
((ProfileCommon)(ProfileBase.Create(username)));
}
Here's an easy way to avoid hand coding this class and
generating it automatically. Before you make the changes in
web.config and create the UserProfile class, run your web project
as it was before. But before running it, turn off SQL Server. This
will make Asp.net execution to break on first call to some Profile
object's property. For ex, if you have a custom property TimeZone
in the Profile object, execution will break on this line:
public virtual int Timezone
{
get
{
return
((int)(this.GetPropertyValue("Timezone")));
It will fail to load the profile object values from database
because database is down. If you scroll up, you will see this is
the class that ASP.NET generates at run time. You will see all the
properties are declared on this class already. So, you can just
copy & paste it in your own class easily!
But after copying, you will realize there's no
[SettingsAllowAnonymousAttribute(true)] attribute. So, you will
have to put them manually. Also after making your own custom class,
you will have to remove all the custom properties declared inside
<properties> node in the web.config.
Now that you have your own Profile class, inside web service,
you can cast (HttpContext.Current.Profile as UserProfile) and then
you can use all the custom properties.
If you don't want to enjoy strongly typed coding on web service,
then you can always use the old way of accessing Profile properties
via: Profile.GetPropertyValue("TimeZone"). But it's no fun.