【问题标题】:ASP.NET MVC Default View Model Binding of cookies to custom objectsASP.NET MVC 默认视图模型 cookie 到自定义对象的绑定
【发布时间】:2010-09-12 18:16:32
【问题描述】:

ASP.NET MVC 2 默认视图模型绑定是否支持将多值 cookie 绑定到自定义对象?在我编写自定义值提供程序之前,我想确保该功能不存在。

所以给定一个类似的动作:

public ActionResult SomeAction(CustomObject foo)

CustomObject 类似于:

public class CustomObject
{
    public string Name { get; set; }
    public int Rank { get; set; }
}

以及作为请求一部分的 cookie,例如:

foo=Name=John&Rank=10

我能否获得默认视图模型绑定以将 cookie 映射到参数,并对 cookie 或 cookie 值的命名进行一些巧妙的调整,例如发布 "foo.Name=John""foo.Rank=10" 会做吗?

【问题讨论】:

    标签: asp.net-mvc-2 cookies binding viewmodel


    【解决方案1】:

    嗯,有一种方法是实现 IModelBinder

    public class CustomObjectModelBinder : IModelBinder {
    
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
            HttpCookie c = controllerContext.HttpContext.Request.Cookies["foo"]
    
            CustomObject value = new CustomObject() {
                foo.Name = c.Values["Name"],
                foo.Rank = c.Values["Rank"]
            }
    
            return CustomObject
        }
    
    }
    

    然后将其添加到您的 Application_Start()

    ModelBinders.Binders.Add(typeof(CustomObject), new CustomObjectModelBinder());
    

    据我所知,您可以将 cookie 对象添加到任何操作中,它会尝试为您绑定它

    【讨论】:

    • 是的,我考虑过,但正在寻找不需要自定义模型绑定的解决方案。在许多情况下,这将是最好的解决方案。
    • 我强烈推荐这种方法。 CustomModel 是一种很好的方法。
    【解决方案2】:

    最后我创造了一些东西来做到这一点。基于Mehdi Golchin 发布的工作,我创建了一个允许这种绑定发生的值提供程序。

    对于那些感兴趣的人,以下是我对上面链接的 Mehdi 作品所做的自定义更改。有关实施的完整详细信息,请参阅链接。这不支持绑定到嵌套对象(例如 Foo.Cell.X),因为我不需要那种复杂程度,但可以通过一些递归来实现。

    protected virtual bool ContainsPrefix(string prefix)
    {
        try
        {
            var parts = prefix.Split(new char[] { '.' }, 2, StringSplitOptions.RemoveEmptyEntries);
    
            switch (parts.Length)
            {
                case 0:
                    return false;
                case 1:
                    return this._context.HttpContext.Request.Cookies.AllKeys.Contains(parts[0]);
                default:
                    var cookie = this._context.HttpContext.Request.Cookies[parts[0]];
                    if (cookie == null) { return false; }
                    return cookie.Values.AllKeys.Contains(parts[1]);
            }
        }
        catch (Exception ex)
        {
            ExceptionPolicy.HandleException(ex, "Controller Policy");
            return false;
        }
    }
    
    protected virtual ValueProviderResult GetValue(string key)
    {
        try
        {
            var parts = key.Split(new char[] { '.' }, 2, StringSplitOptions.RemoveEmptyEntries);
    
            if (parts.Length < 2) { return null; }
    
            var cookie = this._context.HttpContext.Request.Cookies[parts[0]];
    
            if (cookie == null) { return null; }
    
            var value = cookie.Values[parts[1]];
    
            if (value == null) { return null; }
    
            return new ValueProviderResult(value, value, CultureInfo.CurrentCulture);
        }
        catch (Exception ex)
        {
            ExceptionPolicy.HandleException(ex, "Controller Policy");
            return null;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      相关资源
      最近更新 更多