Friday, January 14, 2005

.Net Programming

Tech Blogs
http://dflying.cnblogs.com/
Scott's SP.NET 2.0 Tips, Tricks, Recipes and Gotchas


.NET的重用单元叫集合(assembly). 因此一个集号可认为是--个组件;.NET和C#中的任何程序部包含一个或多个集合. 集会是一个逻辑性自描述性包;它包含MSIL, 元数据和可选资源.在.Net下编写的任何程序,不管它是一个重用的组件还是一个独立的运行控序.它都是一个集合;




1. Regulation
public static bool isEmail(string inputEmail)
{
//inputEmail = NulltoString(inputEmail);
string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
@"\.[0-9]{1,3}\.[0-9]{1,3}\.)(([a-zA-Z0-9\-]+\" +
@".)+))([a-zA-Z]{2,4}[0-9]{1,3})(\]?)$";
Regex re = new Regex(strRegex);
if (re.IsMatch(inputEmail))
return (true);
else
return (false);
}


2. Create cryptographic random password salt number
public static string CreatePwdSalt()
{
// salt size
const int saltSize = 6;

// generate a cryptographic random number using the cryptographic
// service provider
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[saltSize];
rng.GetBytes(buff);

// return the Base64 string representation of the random number
return Convert.ToBase64String(buff);
}



3. Hash Password using salt
public static string CreatePasswordHash(string sPwd, string sSalt)
{
// password hash size
const int hashSize = 100;

string saltAndPwd = string.Concat(sPwd, sSalt);
byte[] result = new byte[hashSize];

// create the service provider
SHA1 sha = new SHA1CryptoServiceProvider();
result = sha.ComputeHash(Encoding.ASCII.GetBytes(saltAndPwd));

// return the password hash value
return Convert.ToBase64String(result);
}

4. Write log to application event log
//Usage:
// catch (Exception ex)
// {
// CommonUtil.LogAppEvent("LoginUser", "Exception encountered during login.", ex, EventLogEntryType.Error, "DAL");
// return LoginResults.LoginException;
// }

public static void LogAppEvent(string funcName, string sMsg, Exception ex, EventLogEntryType eType, string sSource)
{
System.Diagnostics.EventLog lApp = null;
StringBuilder sb = new StringBuilder();

sb.Append("Function: " + funcName + "\n\n");
sb.Append("Message: " + sMsg + "\n\n");

if (ex != null)
{
if (ex.GetType() == Type.GetType("SQLException"))
{
SqlException se = (SqlException)ex;
sb.Append("SQL Exception:\n");
sb.Append("Error: " + se.Number.ToString() + "\n");
sb.Append("Source: " + se.Source + "\n");
sb.Append("On procedure: " + se.Procedure + "\n");
sb.Append("At line number: " + se.LineNumber.ToString() + "\n");
sb.Append("Description: " + se.Message + "\n\n");
sb.Append("Stack: " + se.StackTrace);
}
else if (ex.GetType() == Type.GetType("ArgumentException")
ex.GetBaseException().GetType() == Type.GetType("ArgumentException"))
{
ArgumentException ae = (ArgumentException)ex;
sb.Append("Source: " + ae.Source + "\n");
sb.Append("Description: " + ae.Message + "\n");
sb.Append("Argument: " + ae.ParamName + "\n\n");
sb.Append("Stack: " + ae.StackTrace);
}
else
{
sb.Append("Source: " + ex.Source + "\n");
sb.Append("Description: " + ex.Message + "\n\n");
sb.Append("Stack: " + ex.StackTrace);
}
}

try
{
// Create a new EventLog object
lApp = new System.Diagnostics.EventLog();

// Set the name of the Log
lApp.Source = sSource;

// Write the log
lApp.WriteEntry(sb.ToString(), eType);
}
catch
{
}
finally
{
// Dispose our object
lApp.Dispose();
}
}

5. Web.Config





//意思就是告诉Asp.Net系统,当在程序中使用System.Configuration.ConfigurationSettings.GetConfig("applications/AdminData")这个静态方法来读取applications/AdminData配置节的时候,会调用Corp.Portal.ProviderConfigurationHandler这个类来对这个配置节进行处理, 而Assembly名为Corp.Portal。

























6. Form Authentication
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, oUser.us_login, DateTime.Now, DateTime.Now.AddMinutes(60), false, string.Empty);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(authCookie);
//重定向到Default.aspx
Response.Redirect(Request.ApplicationPath + "/Default.aspx");
// 将已验证身份的用户重定向回最初请求的 URL
FormsAuthentication.RedirectFromLoginPage("*", false);

7. 自定义配置节
.net规定,所有能够处理配置节的类必须要实现IConfigurationSectionHandler接口, 即实现object Create(object parent,object configContext,XmlNode section)方法,这个方法不需要主动调用,它是在ConfigurationSettings.GetConfig这个静态方法的时候自动调用的.

8. web\PageBase.cs基类:
protected void CheckLogin(string application)
{
UserProfile oUP = (UserProfile)System.Web.HttpContext.Current.Session["UserProfile"];
ApplicationInfo info = (ApplicationInfo)oUP.Applications[application];
if (info.app_isLogin == "N") //user not yet logged into the application
{
if (info.app_intsecurity == "N") //different security DB
{
LoginApp();
}
}
}

protected virtual void LoginApp()
{}

protected override void OnError(EventArgs e)
{
ApplicationLog.WriteError(ApplicationLog.FormatException(Server.GetLastError(), UNHANDLED_EXCEPTION));
base.OnError(e);
}


7. 访问当前Session
Session mySession = System.Web.HttpContext.Current.Session;

8. Field Validators not working on different server -- force your application to reference another script version
adding the following tag to the section of the web.config file :

Mutil Tier Structure .Net Sample


Solution: Projects Name Space Objects File

----------Portal Corp.Portal Login Login.aspx.cs
----------Common Corp.Portal.Common CommonUtil CommonUtil.cs
SqlHelper SqlHelper.cs
----------AdminInfo Corp.Portal.Admin.Info UserInfo UserInfo.cs
UserProfile UserProfile.cs
LoginResults EnumInfo.cs
MenuInfo MeneInfo.cs
RoleInfo RoleInfo.cs
GroupInfo GroupInfo.cs
----------AdminBAL Corp.Portal.Admin.BAL UserBAL UserBAL.cs
----------AdminDAL Corp.Portal.Admin.DAL UserDAL UserDAL.cs


=================================================
Login.aspx.cs Corp.Portal
=================================================
protected void btnLogin_Click(Object sender, EventArgs e)
{
UserInfo oUser = new UserInfo(UserDAL.GetUserByEmail(null,null,UserEmail.Text));
if (oUser.us_login == null) {
//Login failed
}
LoginResults result = UserBAL.LoginUser(username, password, "W");
//LoginResults.LoginOK, LoginClientNotAllowed, LoginInvalidUser ...
//if good
UserProfile oUP = UserBAL.GetUserProfile(oUser.us_login, "W");
//Set Session and more process
}

=================================================
EnumInfo.cs Corp.Portal.Admin.Info
=================================================
public enum LoginResults
{
LoginOK = 0,
LoginFailed,
LoginException,
LoginInvalidUser,
LoginNotAllowed,
LoginClientNotAllowed
}

=================================================
UserInfo.cs Corp.Portal.Admin.Info
=================================================
public class UserInfo
{
//Properties
public string us_login;
public string us_online;
...
//A valid DataSet containing a User record in a DataTable
public UserInfo(DataSet ds)
{
LoadUserInfo(ds.Tables[0].Rows[0]);
}
//A valid DataRow representing a User record
public UserInfo(DataRow dr)
{
LoadUserInfo(dr);
}
private void LoadUserInfo(DataRow dr)
{
this.us_login = dr["us_login"].ToString();
...
}
public bool IsOnline();

}


=================================================
UserProfile.cs Corp.Portal.Admin.Info
=================================================
public class UserProfile
{
//Properties
public UserInfo User;
public Hashtable Roles;
public Hashtable Groups;
public Hashtable Applications;
public Stack History;

public UserProfile()
{
this.User = new UserInfo();
this.Roles = new Hashtable();
this.History = new Stack(5);
}
public bool IsInRole(string sRoleCode);
public bool IsInGroup(string sGrpCode);
...
}

=================================================
UserBal.cs Corp.Portal.Admin.BAL
=================================================
public static LoginResults LoginUser(string sLogin, string sPwd, string sClientType)
{
UserInfo oUser = UserDAL.GetUserInfo(null,null,sLogin);
//if good, update user last login
UserDAL.UpdateUserLastLogin(null,sLogin);
//validate the supplied password
string pwdHash = CommonUtil.CreatePasswordHash(sPws, oUser.us_pwdsalt);
if (!pwdHash.Equals(oUser.us_password)) return LoginResults.LoginFailed;
}

public static UserProfile GetUserProfile(string sLogin, string sClientType)
{
SqlConnection cn = null;
DataSet dsGroup = null;
DataSet dsMenu = null;
GroupInfo oGroup = null;
MenuInfo oMenu = null;
UserProfile oProfile = new UserProfile();
cn = new SqlConnection(SqlHelper.GetConnectionString(null));
cn.Open();
oProfile.User = UserDAL.GetUserInfo(null, cn, sLogin);
dsGroup = GroupDAL.GetGroupListByUser(null, cn, sLogin);
//for each row in dsGroup
oGroup = new GroupInfo(dsGroup.Tables[0].Rows[i]);
oProfile.Groups.Add(oGroup.gr_code, oGroup);
}

=================================================
UserDal.cs Corp.Portal.Admin.DAL
=================================================
public static DataSet GetUserByEmail(SqlTransaction tr, SqlConnection cn, string sEmail)
{
bool mustDisposeConnection = false;
SqlCommand cmd = null;
StringBuilder sb = new StringBuilder();
sb.Append("SELECT * from Users ");
sb.Append("WHERE us_email = @us_email");
cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = sb.ToString();
cmd.Parameters.Add("@us_email", SqlDbType.VarChar, 128).Value = sEmail;
if (tr == null)
{
if (cn == null)
{
try
{
cn = SqlHelper.GetConnection(SqlHelper.GetConnectionString(null));
mustDisposeConnection = true;
}
catch (Exception ex)
{
...
}
}
try
{
return SqlHelper.ExecuteDataset(cn, cmd);
}
catch
{
...
}
finally
{
if (mustDisposeConnection)
{
if (cn.State == ConnectionState.Open)
cn.Close();
cn.Dispose();
}
}
}
else
{
try
{
return SqlHelper.ExecuteDataset(tr, cmd);
}
catch (Exception ex)
{
...
}
}
}