Question

I am using Entity Framework 4.1 code first and ASP.NET MVC 3. I have a Yahoo User Interface (YUI) datatable on my view. I am getting the data (to populate the grid via JSON).

Flow of getting data:

Controller -> Service -> Repository

My context setup:

public DbSet<Category> Categories { get; set; }

Original Repositry:

public IEnumerable<Category> GetAll()
{
   return db.Categories.ToList();
}

Call to this repository method from my service layer:

public IEnumerable<Category> GetAll()
{
   return categoryRepository.GetAll();
}

My action method to retrieve the data and to pass it to the YUI datatable:

public ActionResult JsonCategoriesList()
{
   JsonEncapsulatorDto<Category> data = new JsonEncapsulatorDto<Category>
   {
      DataResultSet = categoryService.GetAll()
   };

   return Json(data, JsonRequestBehavior.AllowGet);
}

JsonEncapsulatorDto code:

public class JsonEncapsulatorDto<T>
{
   public IEnumerable<T> DataResultSet { get; set; }
}

When I use it this way then there is an error in the datatable. I don't know how to view the error. Nothing is displayed. I debugged and I saw that there is a count of 7 in the DataResultSet. So what I did was to change the repository to use some test data and then it worked. What is the difference and how do I get it to display my results?

Repository with test data:

public IEnumerable<Category> GetAll()
{
   List<Category> list = new List<Category>();
   list.Add(new Category { Name = "Brendan" });
   list.Add(new Category { Name = "Charlene" });

   return list;
   //return db.Categories.ToList();
}

Not sure if you guys want to see my setup of the categories datatable:

<div id="dtCategories"></div>

<script type="text/javascript">

   YAHOO.util.Event.onDOMReady(function () {

      var yuiDataSource = YAHOO.util.DataSource;
      var yuiPaginator = YAHOO.widget.Paginator;
      var yuiDataTable = YAHOO.widget.DataTable;
      var dtCategoriesColumnDefs, dtCategoriesDataSource;
      var dtCategoriesConfigs, dtCategoriesDataTable;

      dtCategoriesColumnDefs = [
         { key: 'Name', label: 'Name' }
      ];

      dtCategoriesDataSource = new YAHOO.util.DataSource('@Url.RouteUrl      (Url.AdministrationCategoryJsonCategoriesList())');
      dtCategoriesDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
      dtCategoriesDataSource.responseSchema = {
         resultsList: 'DataResultSet',
         fields: [
            { key: 'Name' }
         ]
      };

      dtCategoriesDataTable = new YAHOO.widget.DataTable('dtCategories', dtCategoriesColumnDefs, dtCategoriesDataSource);

   });

</script>

UPDATE:

Category class:

public class Category
{
   public int Id { get; set; }
   public string Name { get; set; }
   public string Description { get; set; }
   public string MetaKeywords { get; set; }
   public string MetaDescription { get; set; }
   public bool IsActive { get; set; }
   public int? ParentCategoryId { get; set; }
   public virtual Category ParentCategory { get; set; }
   public virtual ICollection<Category> ChildCategories { get; set; }
}

Context class:

public class PbeContext : DbContext
{
   public DbSet<Category> Categories { get; set; }
   public DbSet<Tutorial> Tutorials { get; set; }

   protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
   {
      dbModelBuilder.Entity<Category>()
         .HasOptional(c => c.ParentCategory)
         .WithMany(c => c.ChildCategories)
         .HasForeignKey(p => p.ParentCategoryId);
   }
}

UPDATE 2:

I have another view that that gets a list of Product objects (no circular references) and it populates fine. I debugged to see what the data looks like when it is returned. And this is how the objects looked like in the list:

Categories:

[0] [System.Data.Entity.DynamicProxies.Category_9E42BCEDDE8AA695F718BEBE2224E1D34291FCAF82F801F4995EEB8449479C93]
[1] [System.Data.Entity.DynamicProxies.Category_9E42BCEDDE8AA695F718BEBE2224E1D34291FCAF82F801F4995EEB8449479C93]
[2] [System.Data.Entity.DynamicProxies.Category_9E42BCEDDE8AA695F718BEBE2224E1D34291FCAF82F801F4995EEB8449479C93]

...and so on...

Products:

[0] = {MyProject.Core.DomainObjects.Product}
[1] = {MyProject.Core.DomainObjects.Product}
[2] = {MyProject.Core.DomainObjects.Product}

Can it maybe because of how the data is returned??

Was it helpful?

Solution

No idea where your error is. Maybe a recursive Category model (usually that's what happens when you don't use view models and try to pass your EF domain models to the view)? In your example you only need to show a table containing one column which is the name of the category. Passing an entire domain IEnumerable<Category> is like a crime. Maybe missing scripts? Maybe this AdministrationCategoryJsonCategoriesList extension method?

Here's a full working example that I wrote for you and that might get you started:

Model:

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string MetaKeywords { get; set; }
    public string MetaDescription { get; set; }
    public bool IsActive { get; set; }
    public int? ParentCategoryId { get; set; }
    public virtual Category ParentCategory { get; set; }
    public virtual ICollection<Category> ChildCategories { get; set; }

    // Obviously this will be in your repository but for the purpose of
    // this demonstration let's hardcode some data
    public static IEnumerable<Category> GetAll()
    {
        List<Category> list = new List<Category>();
        list.Add(new Category { Name = "Brendan" });
        list.Add(new Category { Name = "Charlene" });
        return list;
    }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult JsonCategoriesList()
    {
        var data = Category.GetAll().Select(x => new
        {
            // We select only what we need for our view => the name
            // if you need something else, well, select it here
            Name = x.Name
        }).ToList();
        return Json(new { DataResultSet = data }, JsonRequestBehavior.AllowGet);
    }
}

View:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>YUI Test</title>
    <link type="text/css" rel="stylesheet" href="http://yui.yahooapis.com/2.9.0/build/datatable/assets/skins/sam/datatable.css">
</head>
<body>
    <div id="dtCategories"></div>

    <script src="http://yui.yahooapis.com/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
    <script src="http://yui.yahooapis.com/2.9.0/build/element/element-min.js"></script>
    <script src="http://yui.yahooapis.com/2.9.0/build/datasource/datasource-min.js"></script>
    <script src="http://yui.yahooapis.com/2.9.0/build/connection/connection-min.js"></script>
    <script src="http://yui.yahooapis.com/2.9.0/build/datatable/datatable-min.js"></script>


    <script type="text/javascript">
        YAHOO.util.Event.onDOMReady(function () {
            var yuiDataSource = YAHOO.util.DataSource;
            var yuiDataTable = YAHOO.widget.DataTable;
            var dtCategoriesColumnDefs, dtCategoriesDataSource;
            var dtCategoriesConfigs, dtCategoriesDataTable;

            dtCategoriesColumnDefs = [{ key: 'Name', label: 'Name'}];

            dtCategoriesDataSource = new YAHOO.util.DataSource('@Url.Action("JsonCategoriesList")');
            dtCategoriesDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
            dtCategoriesDataSource.responseSchema = {
                resultsList: 'DataResultSet',
                fields: [{ key: 'Name'}]
            };

            dtCategoriesDataTable = new YAHOO.widget.DataTable(
                'dtCategories',
                dtCategoriesColumnDefs,
                dtCategoriesDataSource
            );
        });
    </script>
</body>
</html>

OTHER TIPS

Please post the Category type definition to see if there is a circular reference, This might help: Json and Circular Reference Exception

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top