MVC 5 视图模型中的计算属性,而不是模型类

本文关键字:模型 属性 计算 视图 MVC | 更新日期: 2023-09-27 18:34:43

我搜索了StackOverflow和MSDN,并找到了几个页面,我 感觉会对我有所帮助,但是一旦我尝试在那里实施解决方案 总是与我需要的东西略有不同,所以现在我是 经过数小时的拔头发。

问题:我的模型类中有一个计算属性。类名为"渲染",表示照片渲染的模型。计算属性将用作 Zip 文件的名称,我将在 ONE VIEW 上为用户打包在一起,具体取决于他们所在的渲染详细信息页面。显然,我们不想在模型中执行此操作,因为并非每个视图甚至大多数视图都会使用它。

问:如何将此计算属性移动到我的 ViewModel 中?

下面你会看到我当前和工作..

  • 渲染类
  • 查看模型
  • 控制器和
  • 适用的剃须刀代码

渲染类

public class Render
{
    public Render()
    {
    }
    public int RenderId { get; set; }
    public string ClientName { get; set; }
    public string Title { get; set; }
    public string JobId { get; set; }
    public string Comment { get; set; }
    public ICollection<Image> Images { get; set; }
    public string ZipFileName
    {
        get { return (ClientName + "-" + Title + "-" + JobId)
                .Replace(" ", string.Empty); }
    }
}

查看模型

public class RenderDetailViewModel
{
    public IEnumerable<Render> AllRenders { get; set; }
    private readonly RenderLibContext _db = new RenderLibContext();
    public void PopulateRenderDetailModel(int id)
    {
        AllRenders = _db.Renders.Include("Images")
            .Where(r => r.RenderId == id)
            .ToList();
    }
}

控制器

public ActionResult Detail(int id=1)
{
    var render = _db.Renders.Include("Images")
                    .Include(r => r.Comments.Select(c => c.CommentImages))
                    .Include("VenueType").Include("ScreenCount")
                    .FirstOrDefault(r => r.RenderId == id);
    var model = new RenderDetailViewModel()
    {
        RenderId = render.RenderId,
        ClientName = render.ClientName,
        Title = render.Title,
        JobId = render.JobId,
        RenderMonth = render.RenderMonth,
        RenderYear = render.RenderYear,
        Comment = render.Comment,
        Venue = render.Venue,
        Mapping = render.Mapping,
        DefaultImageId = render.DefaultImageId
    };
    return View(model);
}

剃刀代码(缩写(

@model RenderLib.ViewModels.RenderDetailViewModel
...
@foreach (var group in Model.Images.Select(i => i.Version).Distinct().ToList())
{
  <a href="?Set=@group">Set @counter</a>
  <a href="/Renders/Download/@Model.RenderId?fn=@Model.ZipFileName">Download</a>
  ...
}
@foreach (var images in Model.Images
.Where(i => i.RenderId == Model.RenderId && i.Version == Request.QueryString["Set"]))
{
   <li data-thumb="/ImageStore/@images.Path">
     <a href="javascript:void(0)">
       <img src="~/ImageStore/@images.Path" />
     </a>
   </li>
}

此行上方的所有内容都可以正常工作,但是我的计算属性在错误的位置,我希望它在我的ViewModel

我知道你们中的很多人都希望看到有人提出这样的问题,以显示他们已经尝试过的任何内容,以确保我不只是在没有先尝试某些事情的情况下询问答案,因此以下是在我的 ViewModel 中创建计算属性的众多尝试之一的示例:

查看模型(我的尝试(

public class RenderDetailViewModel
{
    public IEnumerable<Render> RenderById { get; set; }
    private static readonly RenderLibContext _db = new RenderLibContext();
    private readonly Render _model;
    public RenderDetailViewModel(Render r)
    { _model = r; }
    public string ClientName { get { return _model.ClientName; } }
    public string Title { get { return _model.Title; } }
    public string JobId { get { return _model.JobId; } }
    public string ZipFileName
    {
        get { 
            return (ClientName + "-" + Title + "-" + JobId)
                        .Replace(" ", string.Empty); 
        }
    }
    public void PopulateRenderDetailModel(int id)
    {
        RenderById = _db.Renders.Include("Images")
            .Where(r => r.RenderId == id)
            .ToList();
    }
}

这次尝试搞砸了我的控制器,并期望我通过一个论点。这不是我想要做的。任何帮助将不胜感激。我希望我包括了帮助任何可能提供帮助的人所需的一切。

MVC 5 视图模型中的计算属性,而不是模型类

视图模型不应包含任何数据库逻辑。它应该只有简单的属性。此外,您无法在任何需要回发的编辑方案中使用它,因为 a( 您没有无参数构造函数(将引发异常(并且您的属性没有 setter。只需将数据模型的属性复制到视图模型,然后在控制器中执行映射(然后就可以删除数据模型中的ZipFileName(

public class RenderViewModel
{
  public int RenderId { get; set; }
  public string ClientName { get; set; }
  ....
  public IEnumerable<Image> Images { get; set; }
  public string ZipFileName
  {
    get { return (ClientName + "-" + Title + "-" + JobId)
            .Replace(" ", string.Empty); }
  }
}

控制器

public ActionResult Detail(int id)
{
  var render = db.Renders.Include("Images").Where(r => r.RenderId == id).FirstOrDefault();
  var model = new RenderViewModel()
  {
    RenderId = render.RenderId,
    ClientName = render.ClientName,
    ....,
    Images = render.Images.Select(...), // not sure what your trying to do here
  });
  return View(model);
}

视图

@model RenderViewModel
@Html.DisplayFor(m => m.ClientName)
....
@foreach (var group in renders.Images)
{
  // better to use helpers to generate the link
  @Html.ActionLink("Download", "Download", "Renders", new { ID = Model.RenderId, fn = Model.ZipFileName })
}

请注意,我对选择与每个渲染关联的图像时尝试执行的操作感到困惑。对于每个图像,您生成一个相同的链接(基于渲染的RenderIdZipFileName(。Image中是否有应包含在路由参数中的属性,以便每个链接下载不同的内容?