与 ASP.NET MVC 2 中的 SelectList 作斗争

发布于 2024-08-21 18:03:32 字数 1485 浏览 1 评论 0原文

我有一个看起来像这样的模型:

public class SampleModel
{
    public static SampleModel Create()
    {
        return new SampleModel
        {
            Boolean = true,
            // set several more properties...
            Colors = new SelectList(new[] { "Red", "Green", "Blue" }, "Green")
        };
    }

    public bool Boolean { get; set; }
    // define several more properties...
    public SelectList Colors { get; set; }
}

我让 ASP.NET MVC 使用 Html.DisplayForModel() 自动为我的详细信息视图和 Html.EditorForModel() 构建属性code> 我的编辑视图。

结果:

  • 编辑视图效果很好。 颜色 显示为包含三个项目(红色、绿色和蓝色)的菜单,默认情况下选择绿色。

  • 但是,对于“详细信息”视图,我得到“False True False”,这显然是菜单中每个项目的 IsSelected 值的列表。那绝对不是我想要的。我希望它只显示“绿色”。

  • 另一个问题是,如果我尝试在控制器中执行 UpdateModel(sampleModel) ,我会收到错误“没有为此对象定义无参数构造函数”。这大概是因为 Colors 是一个 SelectList,而 SelectList 没有无参数构造函数,因此无法完成绑定。

所以,我想我明白问题是什么,但我确实可以为这种情况使用一个好的解决方案,当您拥有带有外键的模型对象时,这种情况似乎会经常出现。

一些问题

  1. 如何让颜色显示为编辑视图的菜单,但在详细信息视图中仅显示为简单的字符串值(例如“绿色”) ?
  2. 更新包含 SelectList 的模型时,如何防止出现“无参数构造函数”错误?
  3. 如果我的 Model/ViewModel 实际上包含外键 ColorId,而不是 Colors,那么让“详细信息”视图显示当前颜色名称的最佳实践是什么编辑视图显示一个菜单,其中包含我的数据库的 Color 表中列出的所有颜色名称。如果有帮助,我将使用 LinqToSql (SqlMetal) 来生成我的模型类。

I have a model that looks something like this:

public class SampleModel
{
    public static SampleModel Create()
    {
        return new SampleModel
        {
            Boolean = true,
            // set several more properties...
            Colors = new SelectList(new[] { "Red", "Green", "Blue" }, "Green")
        };
    }

    public bool Boolean { get; set; }
    // define several more properties...
    public SelectList Colors { get; set; }
}

I'm letting ASP.NET MVC automatically scaffold the properties using Html.DisplayForModel() for my Details view and Html.EditorForModel() for my Edit view.

Results:

  • The Edit view works great. Colors shows up as a menu with three items (Red, Green, and Blue), and Green is selected by default.

  • For the Details view, however, I get "False True False", which is apparently a list of the IsSelected value for each item of the menu. That is definitely not want I want. I would like it to just display "Green".

  • A further problem is that, if I try to do UpdateModel(sampleModel) in my controller, I get the error, "No parameterless constructor defined for this object." This is presumably because Colors is a SelectList, and there is no parameterless constructor for SelectList, so it can't complete the binding.

So, I think I understand what the problems are, but I could really use a good solution for this scenario, which seems to come up a lot when you have models objects with foreign keys.

Some questions:

  1. How do I get Colors to show up as a menu for the Edit view but as just a simple string value (e.g., "Green") in the Details view?
  2. How can I prevent a "no parameterless constructor" error when updating a model that contains a SelectList?
  3. If my Model/ViewModel actually contained a foreign key, ColorId, instead of Colors, what would be the best practice for getting the Details view to show the name of the current color and the Edit view to show a menu containing all the color names listed in the Color table of my database. If it helps, I'm using LinqToSql (SqlMetal) to generate my model classes.

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

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

发布评论

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

评论(1

长途伴 2024-08-28 18:03:32

您的问题都源于您将 SelectList 作为模型属性公开这一事实。根据具体情况,我可能会这样做:

  1. 创建 3 个单独的模型类:一个由 LinqToSql 对象(或它们周围的包装器)组成的“域”模型和两个视图模型,一个用于详细信息视图,一个用于详细信息视图。一个用于编辑视图。

  2. 详细信息视图模型应包含当前选择的颜色名称。 “详细信息”操作将使用域对象中的 FK 关系或通过手动查找所选颜色的详细信息来设置此属性。

  3. 编辑视图模型应包含所选颜色 ID 的属性。它还应包含可用颜色选项的选择列表,并将所选值设置为当前选定的 ID。

  4. 处理表单帖子的编辑操作应该接受编辑视图模型的实例,并且应该将这些更改映射到域模型上。由于所选颜色公开为一个简单的属性,而不是一个选择列表,因此很容易验证并映射回业务对象。

如果您的情况非常简单,您可能可以使用用于“查看”和“编辑”的单个视图模型,甚至可以将域对象直接传递到“详细信息”视图。无论如何,只要您从模型中删除 SelectList 并将所选颜色公开为简单 ID,那么您应该没问题。

Your problems all stem from the fact that you're exposing a SelectList as a model property. Depending on the exact situation, I'd probably do something like:

  1. Create 3 separate model classes: one "domain" model consisting of your LinqToSql objects (or wrappers around them) and two view models, one for the Details view and one for the Edit view.

  2. The Details view model should contain the currently selected color name. The Details action would set this property, either using the FK relationship in your domain objects or by manually looking up the details for the selected color.

  3. The Edit view model should contain a property for the selected color's ID. It should also contain a select list of available color options, with the selected value set to the currently selected ID.

  4. The Edit action that handles the form post should accept an instance of the Edit view model and should map those changes onto the domain model. Since the selected color is exposed a simple property, rather than a select list, it's easy to validate and map back onto the business object.

If your situation is very simple you might be able to get away with a single view model for both View and Edit, or even passing the domain object directly to the Details view. In any case, as long as you remove the SelectList from your model and expose the selected color as a simple ID then you should be OK.

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