Question

I have a finalist page that displays a list of finalists, that are clickable into a single-view page. I have the XML document being passed into a model and am spilling that data onto the main finalists page, but I can't seem to figure out how to grab the clicked finalist's id and display only that finalist on the single-view page.

Any help is appreciated, here is my controller right now:

I am trying to pass the newly created model in to the singleView class, but I'm not sure how to filter it to know which finalist was clicked on, and which finalist to display on the single-view page.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using ProjectX_Awards.Models;

namespace ProjectX_Awards.Controllers
{
    public class FinalistsController : Controller
    {
        //
        // GET: /Finalists/

        public ActionResult Index()
        {
            var doc = XElement.Load(HttpContext.Server.MapPath("~/finalist.xml"));
            var finalists = doc.Descendants("finalist").Select(f => new Models.Finalist()
                {
                    Id = (int)f.Attribute("id"),
                    Name = f.Descendants("name").First().Value,
                    Description = f.Descendants("description").First().Value,
                    Link = f.Descendants("webLink").First().Value,
                    Photo = f.Descendants("photoUrl").First().Value
                });

            return View(finalists);
        }

        public ActionResult SingleView(Finalist model)
        {
            var singleFinalist = model;

            return View(singleFinalist);
        }

    }
} 
Was it helpful?

Solution

If you want to pass a complete model, you need to do a POST to that action-method. The easiest way is to make sure you post all the values in a form-element to the specified action. However, the best thing would be to pass an Id to your SingleView-method. This allows you to do a get to that page, instead of having to post a complete object:

public ActionResult SingleView(int id)
{
    var singleFinalist = model;
    var doc = XElement.Load(HttpContext.Server.MapPath("~/finalist.xml"));
    var finalist = doc.Descendants("finalist").Where(f => (int)f.Attribute("id") == id)
                                              .Select(f => new Models.Finalist()
    {
        Id = (int)f.Attribute("id"),
        Name = f.Descendants("name").First().Value,
        Description = f.Descendants("description").First().Value,
        Link = f.Descendants("webLink").First().Value,
        Photo = f.Descendants("photoUrl").First().Value
    })
    .FirstOrDefault;

    return View(finalist);
}

Then in your finalists-page you can just emit an a-tag like this:

@foreach(var finalist in Model)
{
    <a href="/yourController/SingleView/@finalist.id">Detail</a>
    // or
    @Html.ActionLink("SingleView", "YourController", new { id = finalist.id })
}

EDIT Adding a simple caching method, so the XML is not reloaded everytime:

public ActionResult Index()
{
    return View(GetAllFinalists());
}

public ActionResult SingleView(int id)
{
    var doc = XElement.Load(HttpContext.Server.MapPath("~/finalist.xml"));
    var finalist = GetAllFinalists().Where(f => f.Id == id)
                                    .FirstOrDefault;
    return View(finalist);
}

private IEnumerable<Models.Finalist> GetAllFinalists()
{
    if (HttpContext.Current.Application["finalists"] == null)
    {
        var doc = XElement.Load(HttpContext.Server.MapPath("~/finalist.xml"));
        HttpContext.Current.Application["finalists"] = doc.Descendants("finalist")
            .Select(f => new Models.Finalist()
                {
                    Id = (int)f.Attribute("id"),
                    Name = f.Descendants("name").First().Value,
                    Description = f.Descendants("description").First().Value,
                    Link = f.Descendants("webLink").First().Value,
                    Photo = f.Descendants("photoUrl").First().Value
                });
    }
    return (IEnumerable<Models.Finalist>)HttpContext.Current.Application["finalists"];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top