November Happy Hour will be moved to Thursday December 5th.

Multiple actions inside a single page controller

Vote:
 

So I have been trying to do the following things

  1. Create a custom login for my website users
  2. After log in user fo to there dashboard something like dashboard/index
  3. Now I want to have sub views as follows
    1. dashboard/reports
    2. dashboard/singleReport (maybe I need a new page type for reports here)
    3. dashboard/someAction
    4. ...

The issue I am having is that should I create page types for each of these pages? I would not be adding content through the CMS into these views but the data would be coming from some external api.

It seems strange to create page types for just one page and also not adding data from cms. 

In MVC I was able to have one controller with multiple actions and that okay but here its not the case. I did wrote this code but it seems like wrong way of doing it

    public class DashboardPageController : PageControllerBase
    {
        public async Task Index(DashboardPage currentPage)
        {
            /* Implementation of action. You can create your own view model class that you pass to the view or
             * you can pass the page type for simpler templates */

            MockRystadApi api = new MockRystadApi();
            var model = new DashboardPageModel(currentPage);

            foreach(var item in await api.GetReports())
            {
                model.Reports.Add(new DashboardPageModel.Report{
                    AvailableForModules = item.AvailableForModules,
                    SmallDescription = item.SmallDescription,
                    Title = item.Title,
                    Id = item.Id
                });
            }


            return View(model);
        }

        public ActionResult Report(DashboardPage currentPage, String id)
        {
            MockRystadApi api = new MockRystadApi();
            var model = new DashboardPageModel(currentPage);
            int reportId = int.Parse(id);
            var report = api.GetReport(reportId).Result;
            model.SingleReport.Id = report.Id;
            model.SingleReport.Title = report.Title;
            model.SingleReport.SmallDescription = report.SmallDescription;
            model.SingleReport.AvailableForModules = report.AvailableForModules;

            return View(model);
        }
    }

The issue with the above code is that both the actions require DashboardPageModel to be set. So I would have to fiddle with the model properties. Like when I am viewing all the reports I have the property SingleReport to be null and when I am showing overview of a single report all other data is null. 

Can I get some help here?

#184959
Nov 07, 2017 8:41
Vote:
 

Hi,

Seems like your controllers are good.

Creating a page called "My dashboard page" and browsing to /my-dashboard-page takes me to the Index action and the Index.cshtml
I can browse to /my-dashboard-page/Report/?id=123 to get to the Report action, which would take me to Report.cshtml where I expect to see that report.

However you don't need to use the same Model on both views.

Your Index view could use a completely separate model by simply having different @model registrations

For example some View Models:

public class DashboardPageIndexModel
{
    public DashboardPageIndexModel(DashboardPage currentPage)
    {
        this.CurrentPage = currentPage;
        this.Reports = new List<ReportModel>();
    }

    public DashboardPage CurrentPage { get; set; }

    public List<ReportModel> Reports { get; set; }
}
public class DashboardPageReportModel
{
    public DashboardPageReportModel(DashboardPage currentPage)
    {
        this.CurrentPage = currentPage;
        this.SingleReport = new ReportModel();
    }

    public DashboardPage CurrentPage { get; set; }

    public ReportModel SingleReport { get; set; }
}


public class ReportModel
{
    public string AvailableForModules { get; set; }
    public string SmallDescription { get; set; }
    public string Title { get; set; }
    public int Id { get; set; }
}

And your views starts with

index.cshtml

@model Toders.MultipleActions.Models.ViewModels.DashboardPageIndexModel

report.cshtml

@model Toders.MultipleActions.Models.ViewModels.DashboardPageReportModel

And your Actions are slightly changed as well where I just change to creating the different ViewModels:

public async Task<ActionResult> Index(DashboardPage currentPage)
{
    MockRystadApi api = new MockRystadApi();
    var model = new DashboardPageIndexModel(currentPage);

    foreach (Report item in await api.GetReports())
    {
        model.Reports.Add(new Models.ViewModels.ReportModel
        {
            AvailableForModules = item.AvailableForModules,
            SmallDescription = item.SmallDescription,
            Title = item.Title,
            Id = item.Id
        });
    }


    return View(model);
}

public ActionResult Report(DashboardPage currentPage, string id)
{
    MockRystadApi api = new MockRystadApi();
    var model = new DashboardPageReportModel(currentPage);
    int reportId = int.Parse(id);
    var report = api.GetReport(reportId).Result;
    model.SingleReport.Id = report.Id;
    model.SingleReport.Title = report.Title;
    model.SingleReport.SmallDescription = report.SmallDescription;
    model.SingleReport.AvailableForModules = report.AvailableForModules;

    return View(model);
}

The code is just thrown together and needs some cleanup but I hope you understand the basics.

/Alf

#185302
Edited, Nov 14, 2017 23:25
Vote:
 

When a single PageController has multiple methods that return different Views, these views are not previewable in preview mode in the CMS system. And the content is not inline editable.

How do you deal with this?

#191879
May 02, 2018 12:12
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.