4

カスタムのモデルバインダーがあり、認証クッキーをチェックして値を返します。

public class UserDataModelBinder<T> : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {

        if (controllerContext.RequestContext.HttpContext.Request.IsAuthenticated)
        {
            var cookie =
                controllerContext.RequestContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];

            if (cookie == null)
                return null;

            var decrypted = FormsAuthentication.Decrypt(cookie.Value);

            if (!string.IsNullOrWhiteSpace(decrypted.UserData))
                return JsonSerializer.DeserializeFromString<T>(decrypted.UserData);
        }

        return null;
    }
}

使用する必要がある場合は、それをアクションに渡すだけです。すべてが機能します。

public ActionResult Index(UserData userData)
{
    AccountLoginWidgetVM model = new AccountLoginWidgetVM();
    if (null != userData)
        model.UserData = userData;

    return View(userData);
}

ただし、ユーザーがログインしたら、すべてのページの上部に情報を表示したいので、マスターページで使用したいと思います。私はいくつかのことを試しましたが、うまくいきませんでした

 @Html.RenderPartial("LoginPartial", ???model here??)  
4

2 に答える 2

11

次のようにしました。

  1. マスターページ用に別のビューモデルを定義。

    public class MasterPageViewModel
    {
        public Guid CurrentUserId { get; set; }
        public string CurrentUserFullName { get; set; }
    }
    
  2. インジェクション フィルターとフィルター プロバイダーが追加されました。

    public class MasterPageViewModelInjectorFilterProvider: IFilterProvider
    {
        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
        {
            return new [] {new Filter(new MasterPageViewModelInjectorFilter(), FilterScope.Action, null), };
        }
    
        private class MasterPageViewModelInjectorFilter: IResultFilter
        {
            public void OnResultExecuting(ResultExecutingContext filterContext)
            {
                var viewResult = filterContext.Result as ViewResult;
                if (viewResult == null)
                    return;
    
                if (viewResult.ViewBag.MasterPageViewModel != null)
                    return;
    
                //setup model whichever way you want
                var viewModel = new MasterPageViewModel();
                //inject model into ViewBag
                viewResult.ViewBag.MasterPageViewModel = viewModel;
            }
    
            public void OnResultExecuted(ResultExecutedContext filterContext)
            {
            }
        }
    }
    
  3. フィルター プロバイダーを構成します。

    //in Application_Start
    FilterProviders.Providers.Add(new MasterPageViewModelInjectorFilterProvider());
    
  4. マスターで使用:

    ViewBag.MasterPageViewModel
    

このようにして、優れた非結合アーキテクチャが得られます。もちろん、これを Dependency Injection と組み合わせて (私たちはそうしていますが、わかりやすくするために省略しました)、すべてのアクションに対して任意の方法でアクション フィルターを構成できます。

于 2012-07-31T12:31:48.230 に答える
0

この場合、ViewBag を使用できます。

public ActionResult Index(UserData userData)
{
    AccountLoginWidgetVM model = new AccountLoginWidgetVM();
    if (null != userData)
        model.UserData = userData;

    ViewBag.UserData = userData;
    return View(userData);
}


@Html.RenderPartial("LoginPartial", ViewBag.UserData)

userData が null でないことを確認する必要があります。null の場合、渡されたモデルはビューのデフォルト モデルになります。

于 2012-07-31T12:32:21.517 に答える