1

我已经修改了派生类、接口和视图模型,但我无法创建我需要的东西。

假设我们正在使用以下模型构建 CMS:

文章项目

  • 标题

  • 概括

  • 内容

新闻项目

  • 标题

  • 发布日期

  • 概括

  • 内容

事件项

  • 事件标题

  • 开始日期

  • 结束日期

  • 内容

我正在寻找一种将这些显示标准化为一种格式/视图的方法(例如,我们可以将它们全部显示在同一个 RSS 提要中)。标准化视图可能称为HTMLItem并具有 3 个字段:

  • 标题

  • 概括

  • 内容

ArticleItem将直接转换为HTMLItem,这很简单。

对于NewsItem,我想加入 PublishDate 和内容的前 100 个字符来创建HTMLItem的 Summary 字段。

对于EventItem,我想结合 StartDate 和 EndDate 来创建HTMLItem的 Summary 字段。

最终,我正在寻找能够将 3 个模型传递到旨在显示HTMLItem的单个视图中的最简单、最有效的方法。到目前为止,我最好的方法是为每个模型创建一个“转换器”类,但我不禁觉得有更好的方法来做到这一点。

任何经验、专业知识和建议将不胜感激!

4

3 回答 3

1

为每个专用类创建一个具有标准化属性和构造函数的 ViewModel:

public class HtmlItemViewModel {
    //Properties
    public string Title {get; set;}
    public string Summary {get; set;}
    public string Content {get; set;}

    //Constructor inside HtmlItemViewModel for each one of the specialized classes:
    public HtmlItemViewModel(ArticleItem item)
    {
        this.Title = item.Title;
        this.Summary = item.Summary;
        this.Content = item.Content;
    }

    public HtmlItemViewModel(NewsItem item)
    {
        this.Title = item.Headline;
        this.Summary = String.Format("{0} - {1}", item.PublishDate, item.Summary.Substring(0,1000));
        this.Content = item.Content;
    }

    public HtmlItemViewModel(EventItem item)
    {
        this.Title = item.EventTitle;
        this.Summary = String.Format("{0} - {1}", item.StartDate, item.EndDate);
        this.Content = item.Content;
    }
}

然后,在您用于 RSS 提要的方法上,只需将每个实体传递给每个单独查询的构造函数。像这样:

//Example controller
public class RssController : Controller {
    public ActionResult GetRssFeed(){
        //Assuming you have a service for each item type
        var articleList = ArticleService.GetArticles().Select(s => new HtmlItemViewModel(s));
        var newsItemList = NewsItemService.GetNewsItems().Select(s => new HtmlItemViewModel(s));
        var eventItemList = EventItemService.GetEvents().Select(s => new HtmlItemViewModel(s));

        articleList.AddRange(newsItemList);
        articleList.AddRange(eventItemList);

        return articleList;
    }
}
于 2013-03-04T14:54:11.233 回答
0

您可以在项目中使用Viewmodel Pattern

模型和视图模型是不同的。不要将 ViewModel 与 MVVM 模式混淆。

使用视图模型可以使模型和视图之间的交互更加简单。有时,将其他模型对象作为成员,模型可能会过于复杂,而这些成员可能会将模型对象作为成员等。

通过使用视图模型,您可以很好地简化视图处理的内容。这也将过滤掉智能感知中可以看到的内容,因此如果开发模型的人与开发视图的人不同,那么创建一个简单的视图模型可以让那些只处理 UI 的人更容易。

于 2013-03-04T11:35:27.960 回答
0

最简单且最常见的解决方案是创建一个复合视图模型类。这可以是一个组合类(包含对您的域模型的引用),也可以是一个扁平类,分别引用每个类的属性。

所以你可以这样做:

public class HtmlItemViewModel
{
  public ArticleItem ArticleItem {get; set;}
  public NewsItem NewsItem {get; set;}
  public EventItem EventItem {get; set;}
} 

或这个:

public class HtmlItemViewModel
{
  //Article Item Properties
  public string ArticleTitle {get; set;}
  public string ArticleContent {get; set;}
  public string ArticleSummary {get; set;}
  //News Item Properties
  public string Headline {get; set;}
  public DateTime PublishDate {get; set;}
  public string NewsItemSummary {get; set;}
  public string NewsItemContent {get; set;}
  //Event Item Properties
  public string EventTitle {get; set;}      
  public DateTime StartDate {get; set;}    
  public DateTime EndDate {get; set;}
  public string EventContent {get; set;}
} 

然后,无论您选择哪种方式构建视图模型,您都将视图模型属性映射到控制器中的域模型。您可以手动进行此映射

HtmlItemViewModel.ArticleTitle = ArticleItem.ArticleTitle;
//and so on...

或者您可以使用AutoMapper等第三方工具

在大多数情况下,我倾向于使用扁平视图模型,因为它允许我只发送我需要的数据,不多也不少。它还允许我将用于输入验证的数据注释放在视图模型而不是域模型上。

于 2013-03-04T13:17:08.107 回答