0

I'm able to return the CategoryName field into a list via ViewBag.Categories. I also want to return the CategoryId field and use it to dynamically build the category Details view URL

This is the controller action:

public ActionResult Details(Item item)
{
    var db = new appContext();
    ViewBag.Item = item.ItemTitle;
    ViewBag.ItemLink = "http://localhost:4444/Items/Details/" + item.ItemId;
    ViewBag.Categories = new List<string>(item.Categories.Select(c => c.CategoryName));

    return View();
}

This is the view where the list of categories is returned:

@foreach (string category in ViewBag.Categories)
{
    <li>
        <a href="http://localhost:4444/Categories/Details/???">@category</a>
    </li>
}

How can I return CategoryIdas shown above?

1
  • 2
    I recommend you use @Html.Action("Details", "Categories", new { ID = category.ID }) (based on dotnetoms' answer) to create the link. As soon as you publish your hard coded string above (..//localhost:4444/..) to a server it will fail. Similarly `ViewBag.ItemLink should just be the ID. Commented Jul 18, 2014 at 8:28

4 Answers 4

3

Use custom class for storing categories:

public class CategoryViewModel
{
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
}

Assign it like this:

ViewBag.Categories = item.Categories
    .Select(c => 
        new CategoryViewModel 
        { 
            CategoryId = c.CategoryId, 
            CategoryName = c.CategoryName
        }).ToList();

And in your view use it like this:

@foreach (CategoryViewModel category in ViewBag.Categories)
{
    <li>
        <a href="http://localhost:4444/Categories/Details/@category.CategoryId">@category.CategoryName</a>
    </li>
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can use anonymous types to achieve this:

public ActionResult Details(Item item)
{
    var db = new appContext();
    ViewBag.Item = item.ItemTitle;
    ViewBag.ItemLink = "http://.../Items/Details/" + item.ItemId;
    ViewBag.Categories = item.Categories.Select(c => new { c.CategoryName, c.CategoryId });

    return View();
}

Then in your view:

@foreach (var category in ViewBag.Categories)
{
    <li>
        <a href="http://localhost:4444/Categories/Details/@(category.CategoryId)">@category.CategoryName</a>
    </li>
}

However, you may want to consider replacing the ViewBag with strongly-typed models. It offers a lot of great benefits - including IntelliSense support.

Comments

1

Instead of using a List<string> you could use a:

List<Tuple<int, string>>

E.g.

ViewBag.Categories = item.Categories.Select(cat => 
       Tuple.Create(cat.CategoryID, cat.CategoryName)).ToList();

Comments

0

Define a view-model like this:

 public class CustomViewModel
    {
        public string Item { get; set; }
        public string Title { get; set; }
        public Categories Categories { get; set; }
    }

    public class Categories
    {
        public int Id { get; set; }
        public string CategoryName { get; set; }
    }

    public ActionResult Details(Item item)
    {
        var db = new appContext();
        var model = new CustomViewModel{
            Item = item.ItemTitle,
            ItemLink = "http://localhost:4444/Items/Details/" + item.ItemId,
            Categories = (item.Categories.Select(c => 
                new Categories{ Id = c.Id,CategoryName= c.CategoryName})).ToList()
        };
        return View(model);
    }

and view like:

   @model Categories
   @foreach (Categories category in Model.Categories)
    {
      <li>
        <a href="http://localhost:4444/Categories/Details/@category.CategoryId">@category.CategoryName</a>
     </li>
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.