yuya
yuya

Reputation: 11

Web API en ASP.NET with OData - Model issue

I have a Web API in ASP.NET with OData and I can consume from the service, but the view doesn't print a table. I'm starting with .NET and with MVC.

ERROR: In View: @foreach (var item in Model)

System.NullReferenceException: Object reference not set to an instance of an object.

I have been seeing other similar doubts, which were solved by passing the model in the ActionResult, but I don't know how to do this with OData. Thanks!

MODEL

namespace exchange_rates
{
    using System;
    using System.Collections.Generic;

    public partial class CurrentValue
    {
        public int Id { get; set; }
        public System.DateTime Date { get; set; }
        public string Currency { get; set; }
        public double Rate { get; set; }
    }
}

CONTROLLER

namespace exchange_rates.Controllers
{
    public class CurrentValuesController : ODataController    
    {
        private db_test_bce_Entities db = new db_test_bce_Entities();

        // GET: odata/CurrentValues
        [EnableQuery]
        public IQueryable<CurrentValue> GetCurrentValues()
        {
            return db.CurrentValues;
        }

        // GET: odata/CurrentValues(5)
        [EnableQuery]
        public SingleResult<CurrentValue> GetCurrentValue([FromODataUri] int key)
        {
            return SingleResult.Create(db.CurrentValues.Where(currentValue => currentValue.Id == key));
        }
    }
}

WebApiConfig.cs

namespace exchange_rates
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<CurrentValue>("CurrentValues");
            config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
        }
    }
}

VIEW

@model IEnumerable<exchange_rates.CurrentValue>

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>CurrenciesTable</title>
</head>
<body>
    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Date)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Currency)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Rate)
            </th>
            <th></th>
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Date)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Currency)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Rate)
                </td>
            </tr>
        }
    </table>
</body>
</html>

EDIT

I was trying return my list to the view from the OData Controller and this didn't work for me. Finally, I solved by returning the list from the MVC Controller:

HomeController

public class HomeController : Controller
{
    private db_test_bce_Entitiesdb = new db_test_bce_Entities();

    // GET: Home
    public ActionResult Index()
    {
        var currencies = db.CurrentValues.OrderBy(field => field.Acronym).ToList();

        return View(currencies);
    }
}

Upvotes: 0

Views: 344

Answers (1)

Wheels73
Wheels73

Reputation: 2890

namespace exchange_rates
{
    using System;
    using System.Collections.Generic;

    public class MyViewModel   
    {
       public List<CurrentValue> MyListOfCurrentValues {get;set;} 
    }

    public class CurrentValue
    {
        public int Id { get; set; }
        public System.DateTime Date { get; set; }
        public string Currency { get; set; }
        public double Rate { get; set; }
    }
}

then in the view

 @foreach (var item in Model.MyListOfCurrentValues)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Date)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Currency)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Rate)
                </td>
            </tr>
        }

I'm not familiar with OData... but my controller would look like the below.

public ActionResult MyViewName()
{
            var model = new MyViewModel   
            {
                MyListOfCurrentValues = //Value from data source
            }


            return View("MyViewName", model);
}

Upvotes: 0

Related Questions