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メソッドインターンは、asyc検証の一部としてdomainserviceメソッドを呼び出します。

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

メタデータクラスがドメインサービスと同じプロジェクトにある場合は、UsernameValidator.Shared.csクラスからドメインサービスメソッドを呼び出すことができます。

しかし、ここで私のエンティティモデルとメタデータは別々のライブラリにあります。

任意のアイデアをいただければ幸いです

ジェフはここhttp://jeffhandley.com/archive/2010/05/26/asyncvalidation-again.aspxでasyc検証について素晴らしく説明しました が、これはモデル、メタデータ、共有クラスがすべてサーバー側にある場合にのみ機能します。

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ステートメントの条件を満たす共有バリデーターを再コンパイルしようとします。

私が言ったように。これは、これを行うためのクリーンな方法ではありません。また、名前空間が見つからないという問題が発生する可能性があります。最終的にSilverlightで機能させるには、生成されていないValidator.shared.csでそれらを解決する必要があります。これを正しく行うと、invoke操作を使用して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;
                    }
                };
            }
        }
    }

これはWCFRIAサービスによって生成されるメソッドであり、簡単に分割でき、このような帯域外検証を追加できます。これはこれを行うためのはるかにクリーンな方法ですが、それでもこの検証は現在、Silverlightクライアント側にのみ存在します。

お役に立てれば

于 2012-04-06T07:56:34.957 に答える