繁体   English   中英

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

[英]Calculated Property in MVC 5 ViewModel instead of Model Class

我搜索了StackOverflow和MSDN,发现有几页对我有帮助,但是一旦尝试实施解决方案,总会有一些与我所需要的略有不同,因此,经过数小时的努力,我现在就在这里。

问题:我的模型类中有一个计算的属性。 类名称为“渲染”,代表“照片渲染”的模型。 计算所得的属性将用作Zip文件的名称,我将根据用户所在的“渲染详细信息”页面将其打包在一个视图中。 显然,我们不想在模型中执行此操作,因为并非每个视图,甚至大多数视图都将使用它。

问题:如何将计算所得的属性移到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();
    }
}

这种尝试搞砸了我的控制器,并期望我传递一个参数。 那不是我的目标。 任何帮助将不胜感激。 我希望我提供了所有必要的帮助所有可能提供帮助的人。

视图模型不应包含任何数据库逻辑。 它应该仅具有简单的属性。 同样,您也无法在需要回发的任何编辑方案中使用此方法,因为a)您没有无参数的构造函数(将引发异常),并且属性没有设置程序。 只需将属性从数据模型复制到视图模型,然后在控制器中进行映射(然后可以删除数据模型中的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中是否有应包含在路由参数中的属性,以便每个链接下载不同的内容?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM