如何在数据操作方法之外调用TryUpdateModel

时间:2014-01-21 04:00:25

标签: c# asp.net webforms model-binding

  • VS2012,.NET 4.51

我有一个用户控件,其中包含使用模型绑定的ListView。到现在为止还挺好。我想根据用户操作视图模式的方式显示对象列表。为此,我有一个名为Roles的公共财产。但是当我从里面调用TryUpdateModel()时,我收到了异常:

  

TryUpdateModel'必须通过值提供者或必须通过   从使用的控件的数据操作方法内部调用   数据绑定的模型绑定

现在,虽然我明白我可以通过执行以下操作退出编辑模式:

lvData.EditIndex = -1;

然后在UpdateMethod调用TryUpdateModel()中,我想知道如何在不必连接方法进行更新的情况下调用TryUpdateModel。换句话说,我将IValueProvider参数提供给TryUpdateModel()的方式/位置/内容。

/// <summary>
///     Initialise the user control
/// </summary>
/// <param name="aRoles">List of roles to display</param>
public void Activate(List<RoleInfo> aRoles)
{
    //List we will be binding
    _ViewModel = new List<MembershipRolesViewModel>();

    //Transfer the supplied list into the view model
    foreach (RoleInfo roleInfo in aRoles)
    {
        _ViewModel.Add(new MembershipRolesViewModel
        {
            RoleDisplayName = roleInfo.RoleDisplayName,
            RoleHint = roleInfo.RoleHint,
            RoleName = roleInfo.RoleName,
            RoleSelected = roleInfo.RoleSelected
        });
    }
}

//ListView.SelectMethod points here
public IQueryable<MembershipRolesViewModel> RolesSelect()
{
    return _ViewModel.AsQueryable();
}

//Property to return the roles as manipulated by the user
public List<RoleInfo> Roles
{
    get
    {
        List<RoleInfo> result = new List<RoleInfo>();
        TryUpdateModel(_ViewModel);

        foreach (MembershipRolesViewModel membershipRolesViewModel in _ViewModel)
        {
            result.Add(new RoleInfo
            {
                RoleDisplayName = membershipRolesViewModel.RoleDisplayName,
                RoleHint = membershipRolesViewModel.RoleHint,
                RoleName = membershipRolesViewModel.RoleName,
                RoleSelected = membershipRolesViewModel.RoleSelected
            });
        }

        return result;
    }
}

TryUpdateModel必须传递给值提供者,或者必须从使用模型绑定进行数据绑定的控件的数据操作方法内部调用。

2 个答案:

答案 0 :(得分:1)

从ListView项目中获取值没有简单的方法。您必须循环项目并提取其值。

var bindableTemplate = lv.ItemTemplate as IBindableTemplate;
foreach (ListViewItem item in lv.Items)
{
    var dic = bindableTemplate.ExtractValues(item).Cast<System.Collections.DictionaryEntry>().ToDictionary(k => (string)k.Key, v => v.Value);
    var provider = new DictionaryValueProvider<object>(dic, System.Globalization.CultureInfo.InvariantCulture);

    // Now we can update the item.
    TryUpdateModel<RoleInfo>(model, provider);
}

或强制ListView更新自己的项目。

public List<RoleInfo> Roles
{
    get
    {
        List<RoleInfo> result = new List<RoleInfo>();
        for (int i = 0; i < lv.Items.Count; i++)
            if (lv.Items[i].ItemType == ListViewItemType.DataItem)
                lv.UpdateItem(i, true);

        //...

        return result;
    }
}



public void lv_UpdateItem(int id)
{
    RoleInfo model = //...
    TryUpdateModel(model);
}

希望这有帮助。

答案 1 :(得分:0)

在Action方法之外调用TryUpdateModel是错误的方法。 因为Model Binder与Action方法紧密结合,因此它们可以自动填充以使用我们在UI上填充的数据对属性进行建模。

所以,请在一个动作方法中尝试TryUpdateModel,我希望它能正常工作。