Search code examples
c#asp.net.netasp.net-mvcview

Trying to pass model to view but get a exception


My Issue

I am new and I need some help with the exception below. I deserialize a JSON array and based on all of the reading I've done I believe I am passing the model to the view.

Reading the exception I can deduce that I have some kind of mismatch between models.Rootobject and models.Survey.

I have tried to turn Rootboject into a List but that generates a different exception, I thought that would solve the IEnumerable issue.

So I think I have two problems, I think I have the models mismatched for some reason but also the view is expecting a list and I'm not providing a list. It is worth noting that the view I have auto-generated from the model.

An unhandled exception occurred while processing the request.
InvalidOperationException: The model item passed into the ViewDataDictionary 
is of type 'AgeCareTech.Models.Rootobject', but this ViewDataDictionary 
instance requires a model item of type 
'System.Collections.Generic.IEnumerable`1[AgeCareTech.Models.Survey]'.

Model

namespace AgeCareTech.Models
{
public class Rootobject
{
    [JsonProperty("surveys")]
    public Survey[] surveys { get; set; }
}

public class Survey
{
    [JsonProperty("survey_id")]
    public int survey_id { get; set; }

    [JsonProperty("title")]
    public string title { get; set; }

    [JsonProperty("created_on")]
    public DateTime created_on { get; set; }

    [JsonProperty("number_of_questions")]
    public int number_of_questions { get; set; }

    [JsonProperty("number_of_responses")]
    public int number_of_responses { get; set; }
}

}

View

@model IEnumerable<AgeCareTech.Models.Survey>

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.created_on)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.number_of_questions)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.number_of_responses)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.created_on)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.number_of_questions)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.number_of_responses)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.survey_id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.survey_id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.survey_id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using AgeCareTech.Models;

namespace AgeCareTech.Controllers
{
    public class SurveyHeroSurveyController : Controller
    {
        public async Task<IActionResult> Index()
        {
            string uri = "http://www.mocky.io/v2/5bcb430c2f0000730075beb1";

            Rootobject SurveyHeroInfo = new Rootobject();

            using (HttpClient SurveyHeroAPI = new HttpClient())
            {
                SurveyHeroAPI.BaseAddress = new Uri(uri);
                SurveyHeroAPI.DefaultRequestHeaders.Clear();
                SurveyHeroAPI.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage Response = await SurveyHeroAPI.GetAsync(uri, HttpCompletionOption.ResponseContentRead);

                if (Response.IsSuccessStatusCode)
                {
                    var SurveyHeroResponse = Response.Content.ReadAsStringAsync().Result;

                    SurveyHeroInfo = JsonConvert.DeserializeObject<Rootobject>(SurveyHeroResponse);
                }
            }

            return View(SurveyHeroInfo);
        }
    }
}

Solution

  • You tell your view to expect:

    @model IEnumerable<AgeCareTech.Models.Survey>
    

    ...but you give it a Rootobject object. A Rootobject is not a IEnumerable<Survey>. The error message is clear and very correct. Try telling your view to expect a Rootobject:

    @model Rootobject