Search code examples
c#asp.net-mvcentity-frameworksortingcode-first

Data sorting in mvc


I am really new to ASP.net MVC.In my project I have 2 models. Person.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace CleryAct.Models
{
    public class Person
    {
        [Key]
        public string rockets { get; set; }
        public bool csa { get; set; }
        public string fname { get; set; }
        public string lname { get; set; }
        public string email { get; set; }

        public virtual ICollection<Session> Sessions { get; set; }
    }
}

Session.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace CleryAct.Models
{
    public class Session
    {

        [Key]
        public int ID { get; set; }
        public string rockets { get; set; }
        public virtual Person Person { get; set; }
        public DateTime training { get; set; }


    }
}

I also have 1 view folder with a Details and Index view inside. I created this by adding a new scaffolding item under controller and linking it to my Person Model. In my details folder I an trying to sort the list of dates that comes up. I can not figure out how to call on the dates in my sort function. Persons controller Details .cs

public ActionResult Details(string id, string sortOrder)
{
    ViewBag.CurrentSort = sortOrder;
    ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Person person = db.Persons.Find(id);
    if (person == null)
    {
        return HttpNotFound();
    }
    var persons = from s in db.Persons select s;

    switch (sortOrder)
    {
        default:
            persons = persons.OrderBy(s => s.Sessions);
            break;
        case "date_desc":
            persons = persons.OrderByDescending(s => s.Sessions);
            break;
    }
    return View(person);
}

Details view code

<h2>Details</h2>

<div>
  <h4>Person</h4>
  <hr />
  <dl class="dl-horizontal">

    <dt>
            @Html.DisplayNameFor(model => model.lname), @Html.DisplayNameFor(model => model.fname) 
        </dt>

    <dd>
      @Html.DisplayFor(model => model.lname), @Html.DisplayFor(model => model.fname)
    </dd>

    <dt>
            @Html.DisplayNameFor(model => model.rockets)
        </dt>

    <dd>
      @Html.DisplayFor(model => model.rockets)
    </dd>

    <dt>
            @Html.DisplayNameFor(model => model.email)
        </dt>

    <dd>
      @Html.DisplayFor(model => model.email)
    </dd>
    <br />
    <br />
    <dt>
            @Html.DisplayNameFor(model => model.Sessions)
        </dt>
    <dd>
      <table class="table">
        @foreach (var item in Model.Sessions) {
        <tr>
          <td>
            @Html.DisplayFor(modelItem => item.training)
          </td>
        </tr>
        }
      </table>
    </dd>

  </dl>
</div>
<p>
  @Html.ActionLink("Edit", "Edit", new { id = Model.rockets }) | @Html.ActionLink("Back to List", "Index")
</p>


Solution

  • Try this code

    public ActionResult Details(string id, string sortOrder)
    {
        // don't know what logic stands behind these ViewBag usages.
        // maybe you should get rid of them
        ViewBag.CurrentSort = sortOrder;
        ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        // changes start
        Person person = db.Persons.Include(x => x.Sessions).FirstOrDefault(p => p.rockets == id);
        if (person == null)
            return HttpNotFound();
        person.Sessions = sortOrder == "date_desc" ? 
            person.Sessions.OrderByDescending(s => s.training).ToList() : 
            person.Sessions.OrderBy(s => s.training).ToList();
        // changes end
        return View(person);
    }
    

    You must be missing id field on Person class. Also why not to use int id instead of string id in action? You have integer id in Session - public int ID { get; set; }.