help.axcms.netAxinom Logo
Save Save Chapter Send Feedback
Extending AxUser
AxUser is extendable same way as any other objects in AxCMS.net - both in MS and LS.

What is that all about?

The AxCMS.net uses two databases - MS database and LS database. The latter database is used by the live system running your online web application and contains several AxCMS.net specific tables. It is supposed you as template project developer will reuse this database and place your project specific tables in there.

To provide you with a basic component for managing your application's users we have created the tables AxUsers, AxUserRight and category tables and supplied BL classes to load and save users, authenticate and classify them and give or check user's rights and priviledges.

Actually we have provided you with our own classes, which are being used by CMS in the MS application. The only difference is that they persist into another database.

In case you are not satisfied with the user properties we provide to you by default there is a possibility to exend the user class with your own, project specific fields. This chapter describes how to do it.

Quickstart

To extend the AxUser class with a new integer attribute TimeZone do the following (change the name of the property and the type to any other value type as appropriate):

1. Extend the AxUsers table with your new field.

1.1. Create new file C:\Projects\AxCMS_Sample\Resources_Sample\DB\Create\Live\User.sql. Replace C:\Projects and _Sample as appropriate for your project.

1.2. Put the following into the file (modify it as appropriate):

ALTER TABLE dbo.AxUsers ADD TimeZone int NULL
GO

1.3. Extend your create db script with the call to the new DB script created - open the file C:\Projects\AxCMS_Sample\Resources_Sample\Deploy\CMS\CreateDB.build and add the following to the target "deploy_db_live":

<loadfile file="${AxCMS.Target}\Resources_Sample\DB\Create\Live\User.sql" property="SqlStatement" />
<sql
connstring="${DB.OleConDB.Live}"
transaction="false"
delimiter="GO"
delimstyle="Line"
timeout="60"
verbose="true"
batch="false"
>
${SqlStatement}
</sql>

1.4. Re-run your create db script and the create application.

Now you have the field TimeZone in the AxUsers table.

2. Create a subclass of AxUser class. If you have a special project for your business logic you'll put this class in there, otherwise just put it into your templates project.

[OverridesLsUser]
public class SampleUser: AxUser
{
private int _timeZone;

[AxDbMapToField]
[UserDefinedUI("~/templates/Controls/TimeZoneEditor.ascx", null, "Additional properties")] public int TimeZone
{
get
{
return _timeZone;
}
set
{
if (_timeZone != value) SetDirty();
_timeZone = value;
}
}
}

Pay attention to the class attribute OverridesLsUser. If you omit this, the AxUserAdapter will return you AxUser objects from any loading method and won't save the new fields in any saving method, even if you pass SampleUser to them.

WARNING! You may have only one class marked with OverridesLsUserAttribute among all assemblies places into the bin folder of your live web application.

Pay attention to the method attribute AxDbMapToField and to the call of SetDirty in the property setter. Both are required and part of CMS Persistance Framework. Note: they are not special to extending of live AxUser, you can use any other attribute or possibility of the persistance framework.

3. You can Use the new class in the normal way in the live system.
WARNING! Don't forget your page templates will be also called in the management system in the AxCMS.net WYSIWYG mode. They have access only to the MS database then, so don't use the SampleUser class when your page rendered in CMS. To check that use the method CMSConfigurationSettings.IsCMS.

3.1. To load some user:

int userID = 153;
AxUserAdapter adapter = new AxUserAdapter();
SampleUser user = (SampleUser)adapter.Load(userID);

3.2. To create a new user:

SampleUser user = new SampleUser();
user.Username = "R2D2";
user.Password = "Blubba";
user.TimeZone = 5;
AxUserAdapter adapter = new AxUserAdapter();
adapter.Save(user);

3.3. To update a user:

int userID = 153;
AxUserAdapter adapter = new AxUserAdapter();
SampleUser user = (SampleUser)adapter.Load(userID);
user.TimeZone = 15;
adapter.Save(user);

3.4. To delete a user:

int userID = 153;
AxUserAdapter adapter = new AxUserAdapter();
SampleUser user = (SampleUser)adapter.Load(userID);
adapter.Delete(user);

 

Developing a custom field editor

Custom field editor is a user defined control (ascx) that can be developed either in your templates project or in your extras project. There is only one requirement to that control: it must implement the following interface:

public interface IAxCustomFieldEditor
{
void BindObject(object obj);
void InitControl(UIMapping mapping);
void InitForObject(object obj);
bool IsValid(object obj);
void ReadObject(object obj);
}

The method InitControl will be called early in the page load process. You will get an instance of the UserDefinedUIAttribute (which inherits from UIMapping). This object has three interesting properties: PassThrough, PanelName and Aspect.

In the PassThrough you just get any object you could pass in the attribute declaration. You can use it for example to develop a reusable custom field editor and to configure it using the PassThrough object.

Defining PanelName it is possible to place editors into different panels in CMS interface, grouping them according to some logic.

Aspects are similar to System.Reflection.PropertyInfo - you can use them to read or write data into some property of an object. The difference is that an aspect isn't bound to some particular class - if you have an aspect for property "Text" you can use it for TextBox, Label or YourOwnClassImplementingText.

In the Aspect property of UserDefinedUIAttribute you will get the property to which this attribute belongs. It is recommended that you save this aspect in the view state for the future use in ReadObject and BindObject.

The method BindObject will be called every time the object property should be bound to the user interface provided by your control.

You will get an instance of your BL object as a parameter (in our example it will be SampleUser). If your control is not reusable you can just cast the obj parameter to SampleUser and read your custom property directly. If you want to reuse the control, use the aspect as shown in the sample below.

The method ReadObject will be called every time the object property should be updated from the user interface provided by your control.

You will get an instance of your BL object as a parameter (in our example it will be SampleUser). If your control is not reusable you can just cast the obj parameter to SampleUser and write into your custom property directly. If you want to reuse the control, use the aspect as shown in the sample below.

public partial class TimeZoneEditor: System.Web.UI.UserControl, IAxCustomFieldEditor
{
protected TextBox _text;
protected AxAspect _myAspect;

protected void Page_Load(object sender, EventArgs e){}

protected override object SaveViewState()
{
return _myAspect;
}

protected override void LoadViewState(object savedState)
{
_myAspect = savedState as AxAspect;
}

public void InitControl(UIMapping mapping)
{
_myAspect = mapping.Aspect;
}

public void InitForObject(object obj){}

public void BindObject(object obj)
{
if (_myAspect != null)
{
_text.Text = ((int)_myAspect.ReadFrom(obj)).ToString();
}
else
{
_text.Text = "Aspect unknown";
}
}

public void ReadObject(object obj)
{
if (_myAspect != null)
{
_myAspect.WriteTo(obj, int.parse(_text.Text));
}
}

public bool IsValid(object obj)
{
return true;
}
}

Advanced topics

You can only extend the properites, not remove properties that already exist in AxUser.

It should be possible to use another classes using CMS Persistance Framework as type of the extended attributes (and thereby create a one-to-many relationship). Note that this possibility is theoretical because we haven't tested it yet. 

To manage your LS users from your MS web application (for example in your extras project) create the following adapter:

AxUserAdapter adapter = new AxUserAdapter();
adapter.WebService = new Axinom.AECMS.Db.WebQueryService();
adapter.UserSystem = Systems.LiveSystem;

You can extend your management system's user by placing an assembly with your class inherited from AxUser in the bin folder of the MS web application and using OverridesMsUserAttribute. Note that your extensions won't be presented by the user interface of AxCMS.net and you have to develop your own web form in extras project.

 

Known Issues (version 5.5.1)

If you extend the live AxUser you cannot use fields that doesn't allow nulls. Either declare the field as NULL or declare it as NOT NULL and provide a DEFAULT value.