一、需求:
为了符合国内用户的使用习惯,首先从用户资料方面,有必要增加用户昵称,可以让用户除了一个唯一标志身份的英文登陆ID外,再有一个可以张扬个性的昵称字段,例如dotey(宝玉)。昵称是不能重复的,所以注册时需要判断昵称是否重复。
为了方便管理员对帐号的管理,可以记录用户的注册IP、最后登陆IP和最后活动IP。
QQ在国内的普及,可以增加QQ信息。
二、概要设计:
要修改用户资料,那么首先我们要更改User类,增加相关属性,如果有必要(见备注),我们要在数据库中增加相关字段。
由于用户类和数据库字段的更改,为了不使我们在从数据库中读取/创建/修改用户资料时、缺少这些新增的字段信息,那么我们必须修改相关存储过程和修改从DataReader转成User类的方法PopulateUserFromIDataReader。
为了使用户能输入这些新增的属性并获取用户的输入,那么在UI端我们需要增加相关控件,并将用户输入到控件的内容赋值到User类实例对应的属性中。
备注:在Asp.Net Forums中,将所有的不经常更新的、不需要检索的用户属性,如QQ、MSN、签名档等,处理成二进制流,直接存储在forums_UserProfile表中的StringNameValues[varbinary](7500)字段内。所以当新增这类属性时无需对数据库结构进行更改。现在我们要新增的这些,QQ信息属于这类情况。对于其他的,我们就只能是在数据库中增加相应字段,并修改存储过程了。
public String QQIM
{
get { return GetExtendedAttribute("qqIM"); }
set { SetExtendedAttribute("qqIM", value); }
}
三、具体编码:
3.1 数据库部分:
3.11 首先,我们要在forums_Users表增加相关字段:
[NickName] [nvarchar] (64) NOT NULL DEFAULT (''), --昵称字段
[IPCreated] [nvarchar] (32) NOT NULL DEFAULT (N'000.000.000.000') --注册IP
[IPLastLogin] [nvarchar] (32) NOT NULL DEFAULT (N'000.000.000.000') --最后一次登陆IP
[IPLastActive] [nvarchar] (32) NOT NULL DEFAULT (N'000.000.000.000') --最后一次活动IP——使用记住密码后无需登陆
3.12 这部分更改将可能影响到存储过程:
forums_system_Import_User --导入用户功能
forums_User_CreateUpdateDelete --注册/修改/删除用户资料,要注意注册和修改时都要增加判断当前昵称是否存在。
forums_User_Get --返回用户资料
forums_Users_Online --返回在线用户信息
forums_GetForumModerators --返回斑竹资料
附件: update.sql
3.2 源代码部分:
3.21 在用户类(Components\Components\User.cs)中增加相应属性 Nickname、IPCreated、IPLastLogin、IPLastActive
DateTime dateCreated = DateTime.Now;
DateTime dateLastLogin = DateTime.Now;
DateTime dateLastActive = DateTime.Now;
string nickname;
string ipCreated;
string ipLastLogin;
string ipLastActive;
/// <summary>
/// 昵称
/// </summary>
public string Nickname
{
get { return nickname;}
set { nickname = value;}
}
/// <summary>
/// 注册IP
/// </summary>
public string IPCreated
{
get { return ipCreated;}
set { ipCreated = value;}
}
/// <summary>
/// 最后一次登陆IP
/// </summary>
public string IPLastLogin
{
get { return ipLastLogin;}
set { ipLastLogin = value;}
}
/// <summary>
/// 最后一次活动IP
/// </summary>
public string IPLastActive
{
get { return ipLastActive;}
set { ipLastActive = value;}
}
public String Language
{
get {
string lan = GetExtendedAttribute("language");
if (lan == null || lan == "")
lan = Globals.Language;
return lan;
}
set { SetExtendedAttribute("language", value); }
}
3.22 从DataReader转成User类的方法PopulateUserFromIDataReader(Components\Provider\ForumsDataProvider.cs)中增加对新增字段的支持
user.Nickname = Convert.ToString(dr["Nickname"]);
user.IPCreated = Convert.ToString(dr["IPCreated"]);
user.IPLastLogin = Convert.ToString(dr["IPLastLogin"]);
user.IPLastActive = Convert.ToString(dr["IPLastActive"]);
3.23 在枚举类CreateUserStatus(Components\Enumerations\CreateUserStatus.cs)中增加DuplicateNickname类型,用来判断注册用户时昵称是否重复
/// <summary>
/// The username has been previously disallowed.
/// </summary>
DisallowedUsername,
/// <summary>
/// 重复的昵称
/// </summary>
DuplicateNickname
3.24 在Resources.xml(web\Languages\LanguageName\Resources.xml)中增加在注册/修改用户资料时对昵称字段的描述、昵称不能为空不能重复的提示信息。
<resource name = "CreateNewAccount_NickName">昵称</resource>
<resource name = "CreateNewAccount_NickNameDescription">在本站中将以此名字作为您的公共名称。用3-16个中英文、标点符号或数字组成。 </resource>
<resource name = "CreateNewAccount_nicknameValidator">昵称必须填写。</resource>
<resource name = "CreateNewAccount_CreateUserStatus_DuplicateNickname">昵称已被注册。</resource>
<resource name = "EditProfile_ContactPrivateNickname">昵称:</resource>
3.25在用户注册/修改所对应的皮肤文件(web\themes\SkinName\Skin-CreateNewAccount2.ascx)/(web\themes\SkinName\Skin-EditProfile.ascx)中增加相应控件
Skin-CreateNewAccount2.ascx
<tr>
<td> </td>
</tr>
<tr>
<td align="left" class="fh2">
<b><% = aspnetforums.Components.ResourceManager.GetString("CreateNewAccount_NickName") %></b>
<br />
<% = aspnetforums.Components.ResourceManager.GetString("CreateNewAccount_NickNameDescription") %>
<br />
<asp:textbox id="Nickname" MaxLength="64" runat="server" columns="40"></asp:textbox>
<asp:RequiredFieldValidator EnableClientScript="false" id="nicknameValidator" runat="server" ControlToValidate="Nickname" Cssclass="validationWarning">*</asp:RequiredFieldValidator>
</td>
</tr>
Skin-EditProfile.ascx
<tr>
<td class="f" width="45%">
<% = aspnetforums.Components.ResourceManager.GetString("EditProfile_ContactPrivateNickname") %>
</td>
<td class="fh3">
<asp:TextBox id="Nickname" Size="50" runat="server" MaxLength="50"/>
</td>
</tr>
3.26 用户注册/修改控件(Controls\User\CreateUser.cs)/(Controls\User\EditProfile.cs)中,在InitializeSkin时对新增的几个控件进行初始化,在点击注册/更新事件部分将获取到的昵称内容赋值给用户实例的昵称属性。
CreateUser.cs
TextBox nickname;
RequiredFieldValidator nicknameValidator;
override protected void InitializeSkin(Control skin) {
nickname = (TextBox) skin.FindControl("Nickname");
nicknameValidator = (RequiredFieldValidator) skin.FindControl("nicknameValidator");
nicknameValidator.ErrorMessage = aspnetforums.Components.ResourceManager.GetString("CreateNewAccount_nicknameValidator").Replace("'", @"\'");
}
private void CreateUser_Click(Object sender, EventArgs e) {
// try to create the new user account
User user = new User();
user.Username = username.Text;
user.Nickname = Globals.HtmlEncode(nickname.Text);
user.Email = emailAddress.Text;
user.IPCreated = forumContext.Context.Request.UserHostAddress;
// Nickname already exists!
case CreateUserStatus.DuplicateNickname:
placeHolderValidator.ErrorMessage = aspnetforums.Components.ResourceManager.GetString("CreateNewAccount_CreateUserStatus_DisallowedNickname");
placeHolderValidator.IsValid = false;
break;
}
EditProfile.cs
TextBox nickname;
override protected void InitializeSkin(Control skin) {
nickname = (TextBox) skin.FindControl("Nickname");
nickname.Text = Globals.HtmlDecode(userToEdit.Nickname);
}
public void Update_Click (Object sender, EventArgs e) {
userToEdit.Nickname = Globals.HtmlEncode(nickname.Text);
}
3.27 在对数据库操作的方法CreateUpdateDeleteUser(SqlDataProvider\SqlDataProvider.cs)中,给存储过程传递昵称、注册IP参数
public override User CreateUpdateDeleteUser(User user, DataProviderAction action, out CreateUserStatus status) {
myCommand.Parameters.Add("@NickName", SqlDbType.NVarChar, 64).Value = user.Nickname;
myCommand.Parameters.Add("@IPCreated", SqlDbType.NVarChar, 32).Value = user.IPCreated;
}
上面列举的编码没有QQ资料的新增/修改,没有登陆IP、最后活动IP的记录,还需要补充。