使用 Int64 值将 ModelBinding 到 DropDownListFor

发布于 2024-12-14 20:05:33 字数 1386 浏览 2 评论 0原文

在我的模型中,我有一个对 LookupCategory 的 BIGINT (long/int64) 外键引用。在视图中,我有一个 DropDownListFor ,如下所示:

@Html.DropDownListFor(model => model.LookupKey.LookupCategory, new SelectList(Model.LookupCategories, "ID", "Name"))

创建/编辑视图显示正常,但在选择提交 ModelBinder 的项目时,会抱怨“值'1'无效。”,因为它正在读取它作为字符串而不是长字符串。

有没有办法在不接触模型的情况下解决这个问题?我不想仅仅为了解决这个小问题而实现 ModelBinder,但如果我必须这样做,我已经起草了这个:

public class LookupKeyBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext,
        System.ComponentModel.PropertyDescriptor propertyDescriptor)
    {
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);

        if (propertyDescriptor.PropertyType == typeof(LookupKey))
        {
            var modelState = bindingContext.ModelState[string.Format("{0}.{1}", propertyDescriptor.Name, "LookupCategory")];
            propertyDescriptor.SetValue(bindingContext.Model, long.Parse(modelState.Value.AttemptedValue));

            modelState.Errors.Clear();
            return;
        }
    }
}

它是这样安排的因为我想访问 ModelState,而不必知道表单字段名称(可能会在视图之间更改)。所以我正确地得到了长值,但问题是 DefaultModelBinder 已经完成了它的工作,而不是长值,我需要实际的 LookupCategory (其 ID 是长值)。我不知道如何再次使用默认模型绑定器来使用其默认行为从数据库中查找 LookupCategory。无论如何,对于看起来应该很简单的事情来说,这是很多技巧!

In my models I have a BIGINT (long/int64) foreign key reference to LookupCategory. In the View, I have a DropDownListFor as follows:

@Html.DropDownListFor(model => model.LookupKey.LookupCategory, new SelectList(Model.LookupCategories, "ID", "Name"))

The create/edit views display fine, but upon selecting an item submitting the ModelBinder complains "The value '1' is invalid." because it is reading it in as a string rather than a long.

Is there a way to fix this without touching the model? I'd prefer not to implement ModelBinder just to solve this little issue, but if I must, I've got this drafted:

public class LookupKeyBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext,
        System.ComponentModel.PropertyDescriptor propertyDescriptor)
    {
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);

        if (propertyDescriptor.PropertyType == typeof(LookupKey))
        {
            var modelState = bindingContext.ModelState[string.Format("{0}.{1}", propertyDescriptor.Name, "LookupCategory")];
            propertyDescriptor.SetValue(bindingContext.Model, long.Parse(modelState.Value.AttemptedValue));

            modelState.Errors.Clear();
            return;
        }
    }
}

It's arranged like that because I want access to the ModelState, not have to know the form field names (which could change between views). So I get the long value properly, but the problem is that the DefaultModelBinder already did its work and instead of long, I need the actual LookupCategory (whose ID is the long value). I can't figure out how to use the default model binder again to use its default behavior for finding the LookupCategory from the database. Anyway, this is a lot of trickery for something that seems like it should be simple!

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

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

发布评论

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

评论(1

月光色 2024-12-21 20:05:33

正如我怀疑的那样,检查模型和 LookupKey 类有助于解决该问题。我有过几次类似的经历,再次查看课程表明我没有使用正确的模型属性。

当您将 DropDownListFor 更改为使用 model.LookupKey.LookupCategory.ID 时,它与正确的属性同步,中提琴!

恭喜您发现问题。

As I suspected, examining the model and LookupKey classes helped resolve the issue. I have had several experiences like that, where a second look at the class showed I was not using the correct model property.

When you changed your DropDownListFor to use model.LookupKey.LookupCategory.ID, that synced up with the correct property, and viola!

Congrats on spotting the problem.

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