2

Steven Sanderson は、彼の素晴らしい MVC の本で、セッション変数を設定および取得するカスタム モデル バインダーの例を示し、コントローラーからデータ ストレージ要素を隠します。

これを拡張して、かなり一般的なシナリオに対応しようとしています。セッションに User オブジェクトを保存し、これをすべてのアクション メソッドでパラメーターとして使用できるようにしています。ユーザーの詳細が変更されていない場合、サンダーソンのクラスは正常に機能しましたが、ユーザーが詳細を編集し、修正されたオブジェクトをセッションに保存できるようにする必要があります。

私の問題は、bindingContext.ValueProvider.Keys のキーの数を確認する以外に、GET と POST を区別する方法が見つからないことです。これは間違っているようで、何かを誤解していると確信しています。

誰かが私を正しい方向に向けることができますか? 基本的に、すべてのアクションは現在のユーザーにアクセスする必要があり、UpdateMyDetails アクションは同じオブジェクトを更新する必要があり、すべてセッションによってサポートされます。これが私のコードです...

public class CurrentUserModelBinder : IModelBinder
{
    private const string userSessionKey = "_currentuser";
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
        var user = controllerContext.HttpContext.Session[userSessionKey];
        if (user == null)
            throw new NullReferenceException("The CurrentUser was requested from the CurrentUserModelBinder but no IUser was present in the Session.");

        var currentUser = (CCL.IUser)user;
        if (bindingContext.ValueProvider.Keys.Count > 3)
        {

            var firstName = GetValue<string>(bindingContext, "FirstName");
            if (string.IsNullOrEmpty(firstName))
                bindingContext.ModelState.AddModelError("FirstName", "Please tell us your first name.");
            else
                currentUser.FirstName = firstName;

            var lastName = GetValue<string>(bindingContext, "LastName");
            if (string.IsNullOrEmpty(lastName))
                bindingContext.ModelState.AddModelError("LastName", "Please tell us your last name.");
            else
                currentUser.LastName = lastName;

            if (bindingContext.ModelState.IsValid)
                controllerContext.HttpContext.Session[userSessionKey] = currentUser;

        }
        return currentUser;
    }
    private T GetValue<T>(ModelBindingContext bindingContext, string key)
    {
        ValueProviderResult valueResult;
        bindingContext.ValueProvider.TryGetValue(key, out valueResult);
        bindingContext.ModelState.SetModelValue(key, valueResult);
        return (T)valueResult.ConvertTo(typeof(T));
    }  
}
4

1 に答える 1

1

IModelBinder の代わりに DefaultModelBinder から継承してみてください。その後、base.BindModel を呼び出して、mvc 1.0 の bindingContext.Model または mvc 2.0 の bindingContext.ModelMetadata.Model を設定できます。

bindingContext.Model の入力をトリガーするには、コントローラーで UpdateModel を呼び出します。

本のステートメントを追加する必要があります

if(bindingContext.Model != null)
throw new InvalidOperationException("Cannot update instances");

ただし、モデルにデータを入力してセッションに保存するように変更してください。

if(bindingContext.Model != null)
{
    base.BindModel(controllerContext, bindingContext);
    //save bindingContext.Model to session, overwriting current.
    return bindingContext.Model
}
于 2010-03-03T19:06:49.610 に答える