0

using .NET Core ASP.NET MVC but getting an InvalidOperationException.

I have a base class of a type Task, and a descendant from this class called 'EMonitoringAlert'.

The view is expecting a model of Task array.

@model SquareHat.Notitiam.Task.Task[]

My controller:

    public async Task<ActionResult> Index(string owner, bool completed = false)
    {
        Contract.Ensures(Contract.Result<ActionResult>() != null);
        ViewBag.Title = "Tasks - Emonitoring Alerts";
        SquareHat.Notitiam.Task.Task[] tasks = (await _taskRepository.Get("MonitoringAlert", TaskOwner.All, completed, new Paging(50))).ToArray();
        // for now we are assuming they are all emonitoring alerts
        for (var index = 0; index < tasks.Length; index++)
        {
            var task = tasks[index];
            if (task.TaskType == "MonitoringAlert")
            {
                StaffDetail staff = null;
                ClientDetail client = null;
                var visits = new Visit[] {};

                var sid = task.Meta.GetAs("StaffId", -1);
                var cid = task.Meta.GetAs("ClientId", -1);
                var sd = task.Meta.GetAs("ScheduledStartTime", DateTime.Now.Date);

                if (cid != -1) client = await _winRostaContext.ClientById(cid);

                if (sid != -1)
                {
                    staff = await _winRostaContext.StaffById(sid);
                    visits = (await _winRostaContext.VisitsBy(sid, sd.Date, sd.EndOfDay())).ToArray();
                }
                tasks[index] = new EMonitoringAlert(task, client, staff, visits);
            }
        }
        return View(tasks);
    }

Ignore lots of the details, in essence, I loop through each generic task and identify if it is a subtype that I have a view model (above code is simplified), at which point I create a descendant class and fill out the 'extra' details. I then replace the base 'task' with the descendant.

You can see quite clearly that the variable I pass to the view is an array of Tasks

Task.Task[] tasks = ....
...
return View(tasks);

However, when we run the code, we get the following error

InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'SquareHat.Notitiam.Web.Models.Views.EMonitoringAlert', but this ViewDataDictionary instance requires a model item of type 'SquareHat.Notitiam.Task.Task[]'.

I would have thought that the framework would understand OOP and class inheritance and not baulked at accepting descendants?

Can anyone suggest how I can make the essence of the code work under .NET Core?

Many thanks

Stephen

p.s. for completeness here is the class declaration for EMonitoringAlert

namespace SquareHat.Notitiam.Web.Models.Views
{
    public class EMonitoringAlert : SquareHat.Notitiam.Task.Task
    {
        public const string DefaultTaskType = "MonitoringAlert";

        public EMonitoringAlert()
        { }

        public EMonitoringAlert(Task.Task task, ClientDetail client, StaffDetail staff, Visit[] careWorkerVisits)
            : base(task)
        {
            Contract.Requires(task != null);
            Client = client;
            CareWorker = staff;
            CareWorkerVisits = careWorkerVisits;
        }

        #region Overrides of Task

        public override string TaskType
        {
            get { return base.TaskType ?? DefaultTaskType; }
            set { base.TaskType = value; }
        }

        #endregion

        public StaffDetail CareWorker { get; set; }
        public ClientDetail Client { get; set; }
        public Visit[] CareWorkerVisits { get; set; }
    }
}
RepellantCoder
  • 141
  • 1
  • 4
  • Are you sure the correct action is being called? You're returning an array in that action, but the exception indicates the view is receiving a single item, not an array. – cwharris Jun 26 '18 at 16:59

1 Answers1

0

According to the exception message, your view is expecting an array of Task items while you are passing a single EMonitoringAlert item.

Henk Mollema
  • 44,194
  • 12
  • 93
  • 104