将验证错误传递回UI

时间:2013-08-25 05:26:36

标签: c# asp.net validation

我有一个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上使用以指示问题。

所以,我的验证器,基本..它有一个方法在保存之前接受用户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;
            }

        }

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

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

但是,我在UI中的save方法需要一个int,如果所有的保存都很好,我只是想要int。如何处理错误发生的时间,我需要一个List&lt;&gt;回来?

我刚刚发布了这样一个想法:我可以创建一个SaveUserDto对象,它是返回类型,并且保存了项目的“Id”以及List?

所以,我发送UserDto,并用e SaveUserDto回复?或者,为了更通用,我发送一个UserDto,并回复一个ResponseDto,它只是一个id(如果项目已保存)和一个错误列表,以及一个bool属性,如果ErrorList.Count&gt; 1?

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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
} 

答案 2 :(得分:1)

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

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

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