ASP.NET MVC的 - 问题与EditorTemplate为ICollection的< T>映射到枚举 [英] ASP.NET MVC - Problem with EditorTemplate for ICollection<T> mapped to Enum

查看:99
本文介绍了ASP.NET MVC的 - 问题与EditorTemplate为ICollection的< T>映射到枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.NET MVC 3(剃刀)的网站,叫做(简体)模型查看

I have an ASP.NET MVC 3 (Razor) website, and a (simplified) model called Review:

public class Review
{
   public int ReviewId { get; set; }
   public bool RecommendationOne
   {
       // hook property - gets/set values in the ICollection
   }
   public bool RecommendationTwo { // etc }
   public ICollection<Recommendation> Recommendations { get; set; }
}

建议如下:

public class Recommendation
{
   public byte RecommendationTypeId
}

我也有一个枚举名为 RecommendationType ,我用它来绘制上述建议。 (基于RecommendationTypeId)

I also have an enum called RecommendationType, which i use to map the above recommendation to. (based on RecommendationTypeId).

总结一下 - 一个单审核许多建议,然后每个这些建议映射到一个特定的枚举类型,我揭露钩性能,以简化模型结合/ code。

So to summarize - a single Review has many Recommendations, and each of those Recommendations map to a particular enum type, i expose hook properties to simplify model-binding/code.

所以,到查看:

@Html.EditorFor(model => model.Recommendations, "Recommendations")

pretty简单。

Pretty simple.

现在,对于编辑模板,我想显示每个可能的 RecommendationType (枚举)一个复选框,如果模型有建议(如在编辑视图),我选中此复选框。

Now, for the editor template, i want to display a checkbox for each possible RecommendationType (enum), and if the model has that recommendation (e.g on edit view), i check the box.

下面是我有:

@model IEnumerable<xxxx.DomainModel.Core.Posts.Recommendation>
@using xxxx.DomainModel.Core.Posts;

@{
    Layout = null;
}

<table>
    @foreach (var rec in Enum.GetValues(typeof(RecommendationType)).Cast<RecommendationType>())
    {
        <tr>
            <td>
                @* If review contains this recommendation, check the box *@
                @if (Model != null && Model.Any(x => x.RecommendationTypeId == (byte)rec))
                {
                    @* How do i create a (checked) checkbox here? *@
                }
                else
                {
                    @* How do i created a checkbox here? *@
                }

                @rec.ToDescription()
            </td>
        </tr>
    }
</table>

由于意见建议 - 我不知道如何使用 @ Html.CheckBoxFor 。通常是采用基于模型的前pression,但我有多大的把握如何绑定到基于当前环状枚举值挂钩财产。例如,它需要做动态 @ Html.CheckBoxFor(X =&GT; x.RecommendationOne) @ Html.CheckBoxFor(X =&GT; X。 RecommendationTwo)

As the comments suggest - i don't know how to use @Html.CheckBoxFor. Usually that takes an expression based on the model, but i'm how sure how to bind to the hook property based on the currently looped enum value. E.g it needs to dynamically do @Html.CheckBoxFor(x => x.RecommendationOne), @Html.CheckBoxFor(x => x.RecommendationTwo), etc.

目前的解决方案,我有(工作),涉及手动构建&LT;输入方式&gt; (包括隐藏字段)

The current solution i have (which works), involves manually constructing the <input> (including hidden fields).

但正如我刚开始编辑模板的窍门,希望有经验的人可以点我在强类型的方向发展。

But as i'm just getting the hang of editor templates, hoping someone with experience can point me in a "strongly-typed" direction.

还是有一个更好的方式(HTML助手),我可以做到这一点?

Or is there a nicer way (HTML Helper) i can do this?

推荐答案

我想通过引入适当的视图模型为方案启动:

I would start by introducing a proper view model for the scenario:

public enum RecommendationType { One, Two, Three }

public class ReviewViewModel
{
    public IEnumerable<RecommendationViewModel> Recommendations { get; set; }
}

public class RecommendationViewModel
{
    public RecommendationType RecommendationType { get; set; }
    public bool IsChecked { get; set; }
}

然后,控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // TODO: query the repository to fetch your model
        // and use AutoMapper to map between it and the 
        // corresponding view model so that you have a true/false
        // for each enum value
        var model = new ReviewViewModel
        {
            Recommendations = new[]
            {
                new RecommendationViewModel { 
                    RecommendationType = RecommendationType.One, 
                    IsChecked = false 
                },
                new RecommendationViewModel { 
                    RecommendationType = RecommendationType.Two, 
                    IsChecked = true 
                },
                new RecommendationViewModel { 
                    RecommendationType = RecommendationType.Three, 
                    IsChecked = true 
                },
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(ReviewViewModel model)
    {
        // Here you will get for each enum value the corresponding
        // checked value
        // TODO: Use AutoMapper to map back to your model and persist
        // using a repository
        return RedirectToAction("Success");
    }
}

和相应的视图(〜/查看/主页/ Index.cshtml

@model YourAppName.Models.ReviewViewModel

@{
    ViewBag.Title = "Index";
}

@using (Html.BeginForm())
{
    @Html.EditorFor(model => model.Recommendations)
    <input type="submit" value="Go" />
}

和最后编辑模板(〜/查看/主页/ EditorTemplates / RecommendationViewModel.cshtml

@model YourAppName.Models.RecommendationViewModel
<div>
    @Html.HiddenFor(x => x.RecommendationType)
    @Model.RecommendationType 
    @Html.CheckBoxFor(x => x.IsChecked)
</div>

现在的看法code被清除,因为它应该。没有如果,没有循环,没有LINQ,没有任何反映,这是控制器/映射层的责任。所以每次你发现自己在你的看法写一些先进的C#逻辑的时间,我会建议你重新考虑你的视图模型,并在必要时进行修改。这就是视图模型适用于:要尽可能接近的视图逻辑

Now the view code is cleaned as it should. No ifs, no loops, no LINQ, no reflection, this is the responsibility of the controller/mapper layer. So every time you find yourself writing some advanced C# logic in your view I would recommend you rethinking your view models and adapt them as necessary. That's what view models are intended for: to be as close as possible to the view logic.

这篇关于ASP.NET MVC的 - 问题与EditorTemplate为ICollection的&LT; T&GT;映射到枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆