1

我有一个 APS.Net 应用程序,它是分层的 - UI-Service-Business-Data Access-Database。

当我保存或更新用户时,例如,我创建了一个 UserDto 对象,在 UI 中填充属性,然后将对象向下传递到层,到数据访问器中的 Save 方法。

保存时,它返回更新或插入用户的 id:

protected void btnSave_Click(object sender, EventArgs e)
        {
            var o = new UserDto
                {
                    DisplayName = txtName.Text,
                    Email = txtEmail.Text,
                    Username = txtUsername.Text,
                    Password = txtPassword.Text,
                    TimeZoneId = ddZones.SelectedValue,
                    Id = Session["SelectedUserId"] == null ? 0 : int.Parse(Session["SelectedUserId"].ToString())
                };

            int id = new UserService(Common.CurrentUserId()).SaveUser(o);

            Response.Redirect("users.aspx");

        }

这一切正常,但我正在向我的业务层添加一个验证层。这将根据一些业务规则验证对象,如果没问题,保存它 - 否则,我希望它返回......某些东西......在 UI 上使用以指示问题。

所以,目前我的验证器 basic.. 它有一个在保存之前接受用户对象的方法,进行验证,然后返回 true 或 false ......它看起来像这样:

public static bool SaveUser(UserDto user)
        {
            if (user == null)
            {
                return false;
            }

            if(user.Username.Length < 4 || user.Username.Length > 15)
                return false;

            if (user.Password.Length < 4 || user.Password.Length > 15)
            {
                return false;
            }

            try
            {
                var m = new MailAddress(user.Email);
                return true;
            }
            catch (FormatException)
            {
                return false;
            }

        }

注意:此方法不会保存......所以我可能会重命名它(虽然它在我的 Validation 类中)。它只是问一个问题,我可以保存这个对象吗?

所以,一些基本的验证。但是,我的返回类型只是 bool。我希望它返回类似 a 的List<String> ValidationErrors东西。

但是,我的 UI 中的保存方法需要一个 int,如果一切都保存得很好,我只需要这个 int。我将如何处理发生错误的时间,我需要一个 List<> 回来?

当我发布此内容时,我突然想到了一个想法:也许我可以创建一个 SaveUserDto 对象,它是返回类型,并保存了项目的“Id”以及一个列表?

所以,我发送一个 UserDto 下来,并用 e SaveUserDto 回复?或者,更通用地说,我发送了一个 UserDto,然后回复一个 ResponseDto,它只包含一个 id(如果项目已保存)和一个错误列表,以及一个 bool 属性,如果 ErrorList.Count > 1 则为 true ?

4

3 回答 3

1

使用这种模式,创建一个自定义验证异常可能是有意义的,您可以在验证错误的情况下抛出该异常。调用方的 try catch 可以查找List<string>异常本身的属性并在 UI 中显示错误。

或者,您可以返回一个带有成功/错误集合的对象。

于 2013-08-25T05:34:18.630 回答
1

改变方法为

public static bool SaveUser(UserDto user, out List<String> ValidationErrors)
{
     // do the stuff
     // in case of error set ValidationErrors 

}

那么您可以将上述方法称为

List<String> ValidationErrors;
if(!SaveUser(user, out ValidationErrors))
{
    //you have errors, show the errors using ValidationErrors
} 
于 2013-08-25T05:35:27.747 回答
1

从我的角度来看,除了演示文稿之外的所有图层都应该避免捕获异常,这样错误就会通过图层冒泡。它仅在最后一层,在演示中,您使用常见的 asp.net 验证器和摘要处理问题以正确显示它们。使用这种方法,您将错误处理的工作留给表示层,您的其他层保持干净和不可知,所有异常都无需更改即可到达顶层。

如果您觉得被迫在内部层中进行错误处理,我只会添加自定义异常,因此您可以捕获它并抛出您自己的 WebUserNotFoundException,而不是获取 NullReferenceException。在这种情况下,添加一个包含所有例外的新项目,并在所有层中引用它。为了创建异常,我将创建一个从异常类继承的基本自定义异常,然后创建每个继承基类的自定义异常。

如果我必须创建 SOA,我只会更改此方法,在这种情况下,我将创建一个基本返回对象,我可以在其中获取请求的信息以及进行服务调用时发生的情况。

于 2013-08-25T06:56:12.383 回答