Display content from a table in the database on an admin page

Topics: Administration, Troubleshooting, Writing modules
Aug 22, 2011 at 6:02 PM

Hi guys,

I'm writing a new new module in Orchard. This module will have an admin component which users can log in and create texts then link these texts to pages dynamically on the admin page. I'm having a problem of display the dummy records from the database table onto the admin page. I can see Orchard retrieve those records using the VS2010 debug helper. But on the view page it displays nothing. I'm very new to Orchard. Please help. Here is my code

public class BenefitRecord:ContentPartRecord
    {
        [Required]
        public virtual string Description { get; set; }
    }

public class Benefit : ContentPart<BenefitRecord>
    {
        public string Description
        {
            get { return Record.Description; }
            set { Record.Description = value; }
        }
    }

public class BenefitHandler:ContentHandler
    {
        public BenefitHandler(IRepository<BenefitRecord> repository)
        {
            Filters.Add(StorageFilter.For(repository));
        }
    }

public class Migrations : DataMigrationImpl {

        public int Create() {
			// Creating table BenefitRecord
			SchemaBuilder.CreateTable("BenefitRecord", table => table
				.ContentPartRecord()
				.Column("Description", DbType.String)
			);

            ContentDefinitionManager.AlterPartDefinition(
                typeof(Benefit).Name, cfg => cfg.Attachable());

            return 1;
        }
    }

public class AdminController : Controller {
        public IOrchardServices Services { get; set; }

        private IContentManager _contentManager;

        public AdminController(IOrchardServices services, IContentManager contentManager) {
            Services = services;
            T = NullLocalizer.Instance;
            _contentManager = contentManager;
        }

        public Localizer T { get; set; }

        public ViewResult Index()
        {
            return View(_contentManager.Query<Benefit, BenefitRecord>().List());
        }
    }
This is the view page
@model IEnumerable<Benefits.Models.Benefit>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            Description
        </th>
        <th></th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id })
        </td>
    </tr>
}

</table>

I'm not sure what did I miss to display the needed information.

Thanks in advance.

Coordinator
Aug 22, 2011 at 6:12 PM

My guess would be that you created those dummy records as orphan content parts, without attaching them to content items. Then again I'm just guessing. You said you can see the records from the debugger. Where did you put the breakpoint? Did you try putting a breakpoint into the view?

Aug 22, 2011 at 6:22 PM

Thanks for the quick reply.

I put the breakpoint inside the controller at 

return View(_contentManager.Query<Benefit, BenefitRecord>().List());

the debugger show me in the _contentManager has the records in the database. These records have type BenefitRecord which is located inside the Handlers attributes.

I will attach this content part into the pages after all. When the page is loaded, it will look for all of the benefits. If there is any, it will display at the end of the page. The admin should be able to control (list, insert, modify, delete) these benefits .

Please help

Tri

 



Coordinator
Aug 22, 2011 at 6:24 PM

Did you try putting a breakpoint into the view?

Aug 22, 2011 at 6:32 PM

I just put as you suggested:

@{
foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id })
        </td>
    </tr>
}
}

The break point at the foreach. However the Model shows nothing.

Please help

Coordinator
Aug 22, 2011 at 7:01 PM

If you separate your return statement into two lines (an assignment to a local variable and then the return View(thelist) statement), so that you have the result of the List() to inspext in the debugger, can you check whether that was already null from the controller?

Aug 22, 2011 at 7:08 PM

You are right

IContentQuery<Benefit, BenefitRecord> allBenefits = _contentManager.Query<Benefit, BenefitRecord>();

return View(allBenefits.List());

The break point is at IContentQuery<Benefit,.....

allBenefits is null

How can I retrieve records from the database to fetch into this page? 

Coordinator
Aug 22, 2011 at 7:10 PM

That seems to confirm my first idea, which was that your dummy benefit records are orphans. If you start creating real content items with that part, they should start to show up in your query.

Aug 22, 2011 at 7:12 PM

So you are saying that the above implementation is correct. Also when I create a method to insert benefits into the database through the part (not from the database), the content should be displayed nicely?

Coordinator
Aug 22, 2011 at 7:18 PM

It *looks* fine, but I may have missed something. You will need to add that part to some content type and then start creating them. Just to be clear, you only need a part if it's going to be attached to content types. Otherwise, the records would be enough, but in that case you wouldn't go through content manager to query, but rather through the repository. Makes sense?

Aug 22, 2011 at 7:22 PM

Ok thanks so much for you help. What you explain makes sense :). I will try it out in a bit.

Tri