将验证错误传递回UI

本文关键字:UI 验证 错误 | 更新日期: 2023-09-27 18:29:00

我有一个APS.Net应用程序,它是分层的-UI服务业务数据访问数据库。

当我保存或更新用户时,例如,我创建一个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上使用以指示问题。

所以,我现在的验证器,基本的。。它有一个方法,在保存之前接受用户obejct,进行验证,然后返回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。我希望它返回类似List<String> ValidationErrors之类的东西。

但是,我在UI中的保存方法需要一个int,如果所有保存都很好,我只需要这个int。当出现错误时,我该如何处理,我需要一个List<>返回

当我发布这篇文章时,我突然想到了一个想法:也许我可以创建一个SaveUserDto对象,它是返回类型,并保存了项目的"Id"和一个List?

所以,我发送了一个UserDto down,并用e SaveUserDto回复?或者,为了更通用,我发送一个UserDto,并用一个ResponseDto回复,它只是有一个id(如果保存了项目)和一个错误列表,如果ErrorList.Count>1,则有一个bool属性,这是真的?

将验证错误传递回UI

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

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

将方法更改为

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
} 

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

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

只有当我必须创建SOA时,我才会改变这种方法,在这种情况下,我会创建一个基本返回对象,在那里我可以获得请求的信息以及进行服务调用时发生的事情。