【问题标题】:asp.net mvc tryupdate failing on custom viewmodel自定义视图模型上的 asp.net mvc tryupdate 失败
【发布时间】:2011-04-04 05:18:58
【问题描述】:

我有一个从 MVC 页面上的插入调用返回的视图模型。

它根据底层模型以及一些计算的属性公开属性。

一切都很好,除非我运行if (tryupdateModel(viewModel))。在这一点上,计算的属性似乎会导致错误并且不会通过 if 语句?

是否可以在此属性上添加注释以防止在tryupdate 中对其进行检查?

或者我如何确切地确定是什么不允许它返回 true?

【问题讨论】:

  • 看起来只有一个数据注释在视图模型中失败了,只要找出失败的原因,在你的if(tryupd...)上设置一个断点

标签: asp.net-mvc asp.net-mvc-3 viewmodel


【解决方案1】:

有没有我可以添加的注释 这个属性,以防止它被 签入 tryupdate 了吗?

禁止更新特定属性的一种方法是使用:

TryUpdateModel(model, null, null, new [] {"SecretProperty"}); // Blacklist
TryUpdateModel(model, new [] {"Prop1", "Prop2", "etc"}); // Whitelist - recommended

另一种是实现自定义ModelBinder,反映属性并忽略不应该更新的属性:

public class ApplicationModelBinder : DefaultModelBinder {
    protected override PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
        var allProps = GetTypeDescriptor(controllerContext, bindingContext).GetProperties();

        var resulting = new PropertyDescriptorCollection(null);
        //Filter out the props with no scaffolding set
        foreach(PropertyDescriptor prop in allProps) {
            if (ShouldIncludeProperty(bindingContext, prop))
                resulting.Add(prop);
        }
        return resulting;
    }


    private static bool ShouldIncludeProperty(ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) {
        var doNotScaffold = propertyDescriptor.Attributes.OfType<ScaffoldColumnAttribute>().Any(x => !x.Scaffold);

        return !doNotScaffold;
    }
}

然后您可以将[ScaffoldColumn(false)] 应用于不可更新的属性。 我使用这种方法。

我如何确定究竟是什么不允许它返回 true?

调用TryUpdateModel 后,您可以检查控制器的ModelState 属性并找出错误所在。

【讨论】:

  • 如何知道第一个例子中parameters的顺序?在modelbinder示例中,我如何强制将其用于模型?因为我在其他地方使用的时间跨度属性的模型绑定器有问题?
  • 模型绑定时参数的顺序无关。关于“强制”:您可以在应用程序启动中注册自定义模型绑定器:ModelBinders.Binders.DefaultBinder = new ApplicationModelBinder()
【解决方案2】:

这取决于您执行验证的方式。如果您正在使用数据注释,则需要删除计算属性上的任何属性。您还需要检查哪个属性未通过验证。您可以在 TryUpdateModel 之后执行以下命令:

var errors = ModelState
    .Where(x => x.Value.Errors.Count > 0)
    .Select(x => new { x.Key, x.Value.Errors })
    .ToArray();

这将为您提供错误列表及其相应的属性,并可能帮助您了解正在发生的事情以及验证失败的原因。

【讨论】:

  • 好的,这是我的时间跨度(我为此编写/复制了一个 custommodelbinder,但似乎我未能注册它或New ModelBinder Post
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-20
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 2012-09-20
  • 2019-05-10
相关资源
最近更新 更多