2

我的 silverlight 解决方案有 3 个项目文件

  1. Silverlight 部分(客户端)
  2. Web 部件(服务器)
  3. 实体模型(我在一个单独的项目中维护了 edmx 和元数据)

元数据文件是具有相关数据注释验证的部分类。

[MetadataTypeAttribute(typeof(User.UserMetadata))]
public partial class User
{
    [CustomValidation(typeof(UsernameValidator), "IsUsernameAvailable")]
    public string UserName { get; set; }
}

现在我的问题是我需要在哪里保留此类 UsernameValidator 如果我的元数据类和 edmx 在服务器端(Web),那么我知道我需要在我的 Web 项目中创建一个 .shared.cs 类,然后添加正确的静态方法。

我的 IsUserAvailable 方法实习生将调用 domainservice 方法作为 asyc 验证的一部分。

   [Invoke]
    public bool IsUsernameAvailable(string username)
    {
        return !Membership.FindUsersByName(username).Cast<MembershipUser>().Any();
    }

如果我的元数据类与我的域服务在同一个项目中,那么我可以从我的 UsernameValidator.Shared.cs 类中调用域服务方法。

但是这里我的实体模型和元数据在单独的库中。

任何想法将不胜感激

Jeff 在这里很好地解释了 asyc 验证 http://jeffhandley.com/archive/2010/05/26/asyncvalidation-again.aspx 但这仅在您的模型、元数据和共享类都在服务器端时才有效。

4

1 回答 1

1

有一种黑客可以做到这一点。这不是一种干净的方法,但这可能是它的工作方式。

因为 .shared 负责代码生成,所以它不会抱怨代码的#if 括号中的某些编译错误。所以你可以做的是在任何项目中创建一个 Validator.Shared.cs 并确保它生成到 silverlight 端。

添加以下代码。并且不要忘记命名空间。

#if SILVERLIGHT
using WebProject.Web.Services;
using System.ServiceModel.DomainServices.Client;
#endif



#if SILVERLIGHT
            UserContext context = new UserContext();
            InvokeOperation<bool> availability = context.DoesUserExist(username);
            //code ommited. use what logic you want, maybe Jeffs post. 
#endif

编译器将忽略此代码部分,因为它不满足 if 语句的条件。同时,在silverlight 客户端,它会尝试重新编译满足if 语句条件的共享验证器。

就像我说的。这不是一个干净的方法来做到这一点。而且您可能会因缺少名称空间而遇到麻烦。您需要在非生成的 Validator.shared.cs 中解决它们,最终让它在 silverlight 中工作。如果你做对了,你可以在 silverlight 中使用调用操作进行验证。但在您的项目中却没有像 Jeff 的帖子那样具有模型和元数据。

编辑:我找到了一种更清洁、更好的方法

您可以在 silverlight 客户端创建部分类并执行以下操作

public partial class User
    {
        partial void OnUserNameChanging(string value)
        {
            //must be new to check for this validation rule
            if(EntityState == EntityState.New)
            {
                var ctx = new UserContext();
                ctx.IsValidUserName(value).Completed += (s, args) =>
                {
                    InvokeOperation invop = (InvokeOperation) s;
                    bool isValid = (bool) invop.Value;

                    if(!isValid)
                    {
                        ValidationResult error = new ValidationResult(
                            "Username already exists",
                            new string[] {"UserName"});
                        ValidationErrors.Add(error;
                    }
                };
            }
        }
    }

这是由 WCF RIA 服务生成的一种方法,可以很容易地进行部分化,您可以像这样添加带外验证。这是一种更简洁的方法,但这种验证现在仍然只存在于 silverlight 客户端。

希望这可以帮助

于 2012-04-06T07:56:34.957 回答