Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 扩展Sanderson';存储在会话中的对象的自定义mvc ModelBinder_Asp.net Mvc_Modelbinders_Imodelbinder - Fatal编程技术网

Asp.net mvc 扩展Sanderson';存储在会话中的对象的自定义mvc ModelBinder

Asp.net mvc 扩展Sanderson';存储在会话中的对象的自定义mvc ModelBinder,asp.net-mvc,modelbinders,imodelbinder,Asp.net Mvc,Modelbinders,Imodelbinder,史蒂文·桑德森(Steven Sanderson)在其精彩的MVC书籍中给出了一个自定义模型绑定器的示例,该绑定器设置并检索会话变量,从而对控制器隐藏数据存储元素 我试图扩展它以适应一个非常常见的场景:我在会话中存储一个用户对象,并将其作为参数提供给每个操作方法。Sanderson的类在用户详细信息不变的情况下工作正常,但现在我需要让用户编辑他们的详细信息并将修改后的对象保存回会话 if(bindingContext.Model != null) { base.BindModel(con

史蒂文·桑德森(Steven Sanderson)在其精彩的MVC书籍中给出了一个自定义模型绑定器的示例,该绑定器设置并检索会话变量,从而对控制器隐藏数据存储元素

我试图扩展它以适应一个非常常见的场景:我在会话中存储一个用户对象,并将其作为参数提供给每个操作方法。Sanderson的类在用户详细信息不变的情况下工作正常,但现在我需要让用户编辑他们的详细信息并将修改后的对象保存回会话

if(bindingContext.Model != null)
{
    base.BindModel(controllerContext, bindingContext);
    //save bindingContext.Model to session, overwriting current.
    return bindingContext.Model
}
我的问题是,除了通过检查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));
    }  
}
公共类CurrentUserModelBinder:IModelBinder
{
private const string userSessionKey=“\u currentuser”;
公共对象绑定模型(ControllerContext ControllerContext,ModelBindingContext bindingContext){
var user=controllerContext.HttpContext.Session[userSessionKey];
if(user==null)
抛出新的NullReferenceException(“CurrentUser是从CurrentUserModelBinder请求的,但会话中没有IUser。”);
var currentUser=(CCL.IUser)用户;
如果(bindingContext.ValueProvider.Keys.Count>3)
{
var firstName=GetValue(bindingContext,“firstName”);
if(string.IsNullOrEmpty(firstName))
bindingContext.ModelState.AddModelError(“FirstName”,“请告诉我们您的名字”);
其他的
currentUser.FirstName=FirstName;
var lastName=GetValue(bindingContext,“lastName”);
if(string.IsNullOrEmpty(lastName))
bindingContext.ModelState.AddModelError(“LastName”,“请告诉我们您的姓氏”);
其他的
currentUser.LastName=LastName;
if(bindingContext.ModelState.IsValid)
controllerContext.HttpContext.Session[userSessionKey]=当前用户;
}
返回当前用户;
}
私有T GetValue(ModelBindingContext,字符串键)
{
ValueProviderResult valueResult;
bindingContext.ValueProvider.TryGetValue(键,out valueResult);
bindingContext.ModelState.SetModelValue(键,valueResult);
返回(T)valueResult.ConvertTo(类型(T));
}  
}

尝试从DefaultModelBinder而不是IModelBinder继承,然后可以调用base.BindModel来填充bindingContext.Model(适用于mvc 1.0)或bindingContext.ModelMetadata.Model(适用于mvc 2.0)

要触发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
}

你在别的地方找到答案了吗?我也需要这样做。我也走了Steven Sanderson建议的路线,但现在我读到了关于自定义模型绑定中数据访问的各种不同观点。我似乎无法在自定义模型绑定器中实现依赖项注入。显然,在自定义模型绑定中不能有IoC。。。