I have searched StackOverflow and MSDN and found several pages that I felt would help me, but once I tried implementing the solutions there was always something slightly different with what I needed so now I am here after hours of hair pulling.

Problem: I have a calculated property in my Model Class. The Class name is Render and represents a model for Photo Renderings. The calculated property will be used as a name for a Zip File I will package together on ONE VIEW for the user depending on which Render Detail page they are on. Obviously we don't want to do this in the Model because not every view or even a majority of views will be using it.

Question: How can I move this calculated property into my ViewModel?

Below you will see my current and working..

  • Render Class
  • View Model
  • Controller &
  • Applicable Razor Code

Render Class

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); }
    }
}

View Model

public class RenderDetailViewModel
{
    public IEnumerable<Render> AllRenders { get; set; }
    private static readonly RenderLibContext _db = new RenderLibContext();

    public void PopulateRenderDetailModel(int id)
    {
        AllRenders = _db.Renders.Include("Images")
            .Where(r => r.RenderId == id)
            .ToList();
    }
}

Controller

public ActionResult Detail(int id)
{
    if (id == null)
       {return new HttpStatusCodeResult(HttpStatusCode.BadRequest);}

    var model = new RenderDetailViewModel();
    model.PopulateRenderDetailModel(id);

    return View(model);
}

Razor Code (Abbreviated)

@model RenderLib.ViewModels.RenderDetailViewModel
...
@foreach (var renders in Model.AllRenders)
{
...
  @foreach (var group in renders.Images.Select(i => i.Version).Distinct().ToList())
  {
    ...
    <a href="/Renders/Download/@renders.RenderId?fn=@renders.ZipFileName">Download</a>
    ...
  }
...
}

Everything above this line works fine, but my calculated property is in the wrong place, I would like it to be in my ViewModel

I know that a lot of you would like to see someone who is asking a question like this to show anything they have already tried to make sure I'm not just asking for answers without attempting something first so below is an example of one of the many attempts to create a calculated property in my ViewModel:

View Model (My Attempt)

public class RenderDetailViewModel
{
    public IEnumerable<Render> AllRenders { 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)
    {
        AllRenders = _db.Renders.Include("Images")
            .Where(r => r.RenderId == id)
            .ToList();
    }
}

This attempt screwed up my controller and expected me to pass in an argument. That is not what I was aiming to do. Any help would be greatly appreciated. I hope I included everything needed to aid anyone who might be able to help.

Related posts

Recent Viewed