views:

49

answers:

3

I have an action method returning a JsonResult in my controller:

    public JsonResult GetDetails()
    {
        var rows = //Linq-To-SQL
        //Linq-To-Entities
        var lifts = (from r in rows
                     group r by new { r.LiftID, r.LiftDate } into g
                     select new
                     {
                         ID = g.Key.LiftID,
                         Date = g.Key.LiftDate.ToShortDateString(),
                         Driver = g.Where(x => x.IsDriver)
                                    .Select(x => x.p).Single().Name,
                         Passengers = g.Where(x => !x.IsDriver)
                                        .Select(x => x.p.Name)
                                        .Aggregate((x, y) => x + ", " + y)
                     }).ToList();
        return Json(lifts);
    }

I use the result in a jQuery script to write out a table.

The data looks like:

ID | Date | Driver | Passengers

1 | 20/06/2010 | David Neale | John Smith, Paul Jones

etc...

I would like the names to be hyperlinks to the route Person\{id} I.e. <a href="\Person\7">David Neale</a>. The p property corresponds to a Person object containing both Name and ID.

I don't want to construct the URL manually. How would I construct the object to contain the names as hyperlinks using the MVC routing engine?

+1  A: 

It's fairly easy.

Just use Url.Action("actionName", "controllerName", params)

It will create a string using the routing engine, so if you change the routes your code will keep workin just fine

Matteo Mosca
A: 

First, I think you have a mistake in your model or in your Linq-To-SQL or Linq-To-Entities querys. Because you don't have an ID for your Persons (Drivers and Passagers), and you will definitly need it if you want a link with an Id of the Person. I think you need to split your Lifts from your Persons and have 2 separate entities (linked by its Id of course).

Second, you need to pass the ID of the Persons from the Controller to the View.

class Lift
{
    public int LiftID { get; set; }
    public DateTime LiftDate { get; set; }
    public IEnumerable<Person> p { get; set; }
}
class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsDriver { get; set; }
}
public JsonResult GetDetails()
{
    var rows = new Lift[] { //Linq-To-SQL and Linq-To-Entities replaced by an example
        new Lift{LiftID = 1, LiftDate= DateTime.Now, p = new Person[] {
            new Person{IsDriver = true,  Id = 1, Name = "David Neale"},
            new Person{IsDriver = false, Id = 2, Name = "John Smith"},
            new Person{IsDriver = false, Id = 3, Name = "Paul Jones"}
        }},
        new Lift{LiftID = 2, LiftDate= DateTime.Now, p = p = new Person[] {
            new Person{IsDriver = true,  Id = 4, Name = "Daniel Faraday"},
            new Person{IsDriver = false, Id = 2, Name = "John Smith"}
        }}
    };
    var lifts = (from r in rows
                 select new
                 {
                     ID = r.LiftID,
                     Date = r.LiftDate.ToShortDateString(),
                     Driver = r.p.Where(x => x.IsDriver)
                                 .Select(x => x.Name).Single(),
                     Passengers = r.p.Where(x => !x.IsDriver)
                                     .Select(x => x.Name)
                                     .Aggregate((x, y) => x + ", " + y)
                 }).ToList();
    return Json(lifts);
}

Then, once you have the ID on the View you use it to make the link using Html.ActionLink:

<%= Html.ActionLink("Person", "Index", new { id = p.Id })%>
Protron
As I said, p represents an object of type `Person`. This type does contain an `ID` property, I just haven't bothered showing you the structure of the type. The `ActionLink` HTML helper won't work because that data is being populated by jQuery on the client side. The data sent back needs to be valid HTML.
David Neale
A: 

If you know the action and controller beforehand, you can do something like:

var baseURL = '<%=Url.Action("MyAction","MyController") %>';

and then manually build your links from jQuery, with href set to something like baseUrl+"/"+personId

Terje
The json data is being returned via an ajax call so I can't use server tags.
David Neale
You can't just declare it globally on (f.ex in `(document).ready(...)` , and simply reference it from your async response? If I'm misunderstanding your problem, seeing some of the view might be helpful.
Terje