ASP.NET MVC 默认视图模型 将 cookie 绑定到自定义对象

发布于 2024-09-19 00:32:47 字数 550 浏览 5 评论 0原文

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" 这样的值可以吗?

Does the ASP.NET MVC 2 Default View Model Binding support binding a multi-value cookie to a custom object? Before I write a custom Value Provider, I would like to be sure that the functionality didn't already exist.

So given an action like:

public ActionResult SomeAction(CustomObject foo)

where CustomObject is something like:

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

and a cookie that is part of the request like:

foo=Name=John&Rank=10

Could I get the Default View Model Binding to map the cookie to the parameter with some clever tweaks to the naming of the cookie or cookie values like posting "foo.Name=John" and "foo.Rank=10" would do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

格子衫的從容 2024-09-26 00:32:48

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

对于那些感兴趣的人,以下是我对上面链接的迈赫迪的作品所做的自定义更改。有关实施的完整详细信息,请参阅链接。这不支持绑定到嵌套对象(例如,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;
    }
}

In the end I created something to do this. Based on the work posted by Mehdi Golchin, I created a value provider that allows this kind of binding to happen.

For those interrested, the following are the custom changes I made to Mehdi's work linked above. See the link for full details on implementation. This doesn't support binding to nested objects (e.g., Foo.Cell.X) because I didn't need that level of complexity, but it would be possible to implement with a bit of recursion.

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;
    }
}
隱形的亼 2024-09-26 00:32:47

好吧,有一种方法可以实现 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 对象添加到据我所知的任何操作,它会尝试为您绑定它

Well, there's one way to do it would be to implement 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
    }

}

Then just add this to your Application_Start()

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

you can add the cookie object to any action as far as i know and it will attempt to bind it for you

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文