代码之家  ›  专栏  ›  技术社区  ›  b0x0rz

如何:处理异常、最佳实践

  •  3
  • b0x0rz  · 技术社区  · 16 年前

    需要实现全局错误处理,因此您可以通过以下示例提供帮助…

    我有这个代码:

    public bool IsUserAuthorizedToSignIn(string userEMailAddress, string userPassword)
            {
                // get MD5 hash for use in the LINQ query
                string passwordSaltedHash = this.PasswordSaltedHash(userEMailAddress, userPassword);
    
                // check for email / password / validity
                using (UserManagementDataContext context = new UserManagementDataContext())
                {
                    var users = from u in context.Users
                                where u.UserEMailAdresses.Any(e => e.EMailAddress == userEMailAddress)
                                    && u.UserPasswords.Any(p => p.PasswordSaltedHash == passwordSaltedHash)
                                    && u.IsActive == true
                                select u;
    
                    // true if user found
                    return (users.Count() == 1) ? true : false;
                }
            }
    

    以及MD5:

    private string PasswordSaltedHash(string userEMailAddress, string userPassword)
            {
                MD5 hasher = MD5.Create();
                byte[] data = hasher.ComputeHash(Encoding.Default.GetBytes(userPassword + userEMailAddress));
    
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    stringBuilder.Append(data[i].ToString("x2"));
                }
    
                Trace.WriteLine(String.Empty);
                Trace.WriteLine("hash: " + stringBuilder.ToString());
                return stringBuilder.ToString();
            }
    

    那么,如何处理这些函数的异常呢?首先从default.aspx页面调用它们。第二个函数只能从类库中的其他函数调用。

    最佳实践是什么?

    • 每个函数内部的环绕代码 try-catch
    • 围绕函数调用 尝试捕捉
    • 还有别的吗??

    如果发生异常怎么办?

    在本例中: 这是一个用户登录,所以不管怎样,即使一切都失败了,用户也应该得到一些有意义的信息-沿着这行:登录确定(只是重定向),登录不正常(错误的用户名/密码),由于内部问题无法登录,抱歉(发生异常)。

    对于第一个函数,我担心数据库访问是否有问题。 不确定第二个问题是否需要处理。

    THNX获取信息。你会怎么做? 需要关于这方面的具体信息(我更容易理解),也需要关于如何处理其他任务/功能的一般信息。

    我环顾了一下互联网,但每个人都有不同的话要说,所以不确定该怎么做…要么在这里投票最多,要么大多数逻辑解释答案:)谢谢。

    3 回复  |  直到 16 年前
        1
  •  3
  •   this. __curious_geek    16 年前

    您的库代码或 在您的 应用程序必须始终只引发 例外,不用担心 去对付他们。

    这一点很重要,因为您可以在许多地方将此库用于不同的目的。

    在应用程序表示层中,如果您正在使用库代码,并且知道可能的异常,那么一定要用try/catch来捕获它们。

    既然您使用的是ASP.NET,我建议您编写一个公共页基类,并在 Page_Error 捕获页面上所有未处理的异常的事件。

    甚至超出了你可以使用的范围 Application_Error 即使在global.asax中,也可以捕获应用程序、模块、处理程序、服务、页面等任何部分中未处理的异常。

    我强烈建议不要去 处理所有问题的一般做法 全局应用程序中出现异常\错误。

        2
  •  4
  •   jammycakes    16 年前

    两条黄金法则:

    1. 如果一个方法不能做其名称所说的事情,则抛出异常。
    2. 除非你知道如何处理异常,否则不要捕获异常。

    记住,一个例外表明出了什么问题,而那个特殊的事情可能不是你想的那样。(内存不足、堆栈溢出、第三方服务故障、部署失败,导致程序集丢失、配置错误、安全异常等)。

    除了极少数的异常,您应该看到的惟一一个Pokemon异常处理的地方是代码的最顶层,在那里异常应该发布到某个地方。例如,在global.asax文件中的application_error方法中。

    以下是一些对您有帮助的链接:

        3
  •  3
  •   Ed Sykes    16 年前

    您需要考虑方法定义的契约。如果一个方法不能完成它的契约,那么您需要一个异常。从方法的契约的角度来看,方法中抛出的异常应该转换为有意义的异常。

    在第一种情况下,我将捕获语句执行可能引发的任何异常(例如数据库错误),并将其转换为类似于authorizationexception的内容。从方法契约的角度来看,允许异常直接传播是没有意义的。例如,当方法正在履行作者是否被授权的契约时,允许数据库异常从方法中逸出是没有意义的。

    将这种方法的思想用作合同,可以让您做出正确的决策。如果一个方法协定正在登录到数据库中,或者进行了一些数据库操作,那么允许传播异常可能很有意义。

    具体化:使用第一个示例:

    public bool IsUserAuthorizedToSignIn(string userEMailAddress, string userPassword)
        {
            try
            {
                // get MD5 hash for use in the LINQ query
                string passwordSaltedHash = this.PasswordSaltedHash(userEMailAddress, userPassword);
    
                // check for email / password / validity
                using (UserManagementDataContext context = new UserManagementDataContext())
                {
                    var users = from u in context.Users
                            where u.UserEMailAdresses.Any(e => e.EMailAddress == userEMailAddress)
                                && u.UserPasswords.Any(p => p.PasswordSaltedHash == passwordSaltedHash)
                                && u.IsActive == true
                            select u;
    
                    // true if user found
                    return (users.Count() == 1) ? true : false;
                }
            }
            catch(ThisException e)
            {
                thrown new AuthorisationException("Problem1 occurred");
            }
            catch(ThatException e)
            {
                thrown new AuthorisationException("Problem2 occurred");
            }
            catch(OtherException e)
            {
                thrown new AuthorisationException("Problem3 occurred");
            }
        }
    

    您可能还希望对授权异常设置内部异常:

            catch(ThisException e)
            {
                thrown new AuthorisationException("Problem1 occurred", e);
            }
    

    然后您的客户机代码可以这样做:

    try
    {
        if(User.IsUserAuthorizedToSignIn)
        {
            // Let the magic happen
        }
        else
        {
            // No rights
        }
    }
    catch(AuthorisationException e)
    {
        // Let the user know there is something up with the system. 
    }
    

    您可能决定不想在即时呼叫站点捕获授权异常,因为您无法通知用户。所以你可以让它传播到一个你可以用它做点什么的层次。

    希望有帮助!