1

I am getting started with Angular and ASP Web Api and have hit a brick wall, would really welcome some help.

I have a website I'm developing that has a news page, and a news feed of recent items to the home page. It's using angular with a simple JSON file which I update manually, all works well. I want to write an MVC4 Web app to allow users to update news and a web api for angular to connect to.

I've started a trial project and have the web app project for the CRUD of the records connected to SQL Server all working fine. I have built a web api based on the standard VS templates which works as far as I can see the JSON data in the browser when debugging, but I can't get angular to work, and I'm at a loss how to debug it any further. My model has a relationship between two tables, and this appears to make the JSON returned quite complex. I would like to know the best approach, do I need to modify my controller to return just the data I want, or modify how the data is returned in global.asax? Thank you.

My model:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace admin.Models
{
    public class NewsItem
    {
        public virtual int id { get; set; }
        public virtual int NewsTypeId { get; set; }
        public virtual string title { get; set; }
        public virtual string details { get; set; }
        public virtual DateTime date {get; set;}
        public virtual string image { get; set; }
        public virtual string url { get; set; }
        public virtual DateTime? embargodate { get; set; } //force as nullable
        public virtual NewsType NewsType { get; set; }
    }

    public class NewsType
    {
        public virtual int NewsTypeId { get; set; }
        public virtual string description { get; set; }
    }
}

My controller:

using webapi.Models;

namespace webapi.Controllers
{
    public class NewsController : ApiController
    {
        private DBNewsContext db = new DBNewsContext();

        // GET api/News
        public IEnumerable<NewsItem> GetNewsItems()
        {
            var newsitems = db.NewsItems.Include(n => n.NewsType);
            return newsitems.AsEnumerable();
        }

        // GET api/News/5
        public NewsItem GetNewsItem(int id)
        {
            NewsItem newsitem = db.NewsItems.Find(id);
            if (newsitem == null)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
            }

            return newsitem;
        }

global.asax:

public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //These lines added by BL to return only json

            GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
        }
    }

json returned:

[{"NewsType":{"RelationshipManager":{"_relationships":[[]]},"NewsTypeId":1,"description":"Event"},"RelationshipManager":{"_relationships":[{"EntityKey":{"$id":"1","EntitySetName":"NewsTypes","EntityContainerName":"DBNewsContext","EntityKeyValues":[{"Key":"NewsTypeId","Type":"System.Int32","Value":"1"}]}}]},"id":1,"NewsTypeId":1,"title":"Hub Grub","details":"Greek Night","date":"2015-09-28T00:00:00","image":"test.jpg","url":"test.html","embargodate":"2015-09-24T00:00:00"},{"NewsType":{"RelationshipManager":{"_relationships":[[]]},"NewsTypeId":2,"description":"Article"},"RelationshipManager":{"_relationships":[{"EntityKey":{"$id":"2","EntitySetName":"NewsTypes","EntityContainerName":"DBNewsContext","EntityKeyValues":[{"Key":"NewsTypeId","Type":"System.Int32","Value":"2"}]}}]},"id":2,"NewsTypeId":2,"title":"How to write a CV","details":"Find out how to write a great CV","date":"2015-09-24T00:00:00","image":"test2.jpg","url":"test2.html","embargodate":"2015-09-30T00:00:00"}]

angular:

// get news controller
function NewsCtrl($scope, $http) {
    //$http.get('js/news.json')
    $http.get('http://localhost:49232/api/news')
        .success(function (data) { $scope.items = data.data; })
        .error(function (data) { console.log('error') });
}

<div ng-controller="NewsCtrl" class="row">
                <div ng-repeat="item in items" class="col-md-4 col-sm-12">
                    <h3>{{ item.title }}</h3>
                    <h4>{{ item.date }}</h4>
                    <p>{{ item.details }}</p>
                    <!--<img class="img-responsive" src="{{ item.image }}" />-->
                </div>
            </div>

2 Answers 2

2

I generally have my Controllers return type IHttpActionResult:

public IHttpActionResult Get()
{
    var newsitems = db.NewsItems.Include(n => n.NewsType);
    return Ok(newsitems);
}

Then the 'data' object in your http call back contains the json.

Sign up to request clarification or add additional context in comments.

2 Comments

IHttpActionResult is only supported in Web API 2.x and on.
The type of the return object shouldn't matter, besides the action already returns valid JSON.
1

If you only want to return particular data from the model you can create a DTO object that contains only the data you need and then assign the values you want to the DTO.

So in your controller something like:

   // GET api/News/5
            public NewsItemDTO GetNewsItem(int id)
            {
                NewsItem newsitem = db.NewsItems.Find(id);
                if (newsitem == null)
                {
                    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
                }
               var newsitemdto = new NewsItemDto()
                 {
                  // map what you want in here
                  newsitemdto.title = newsitem.title
                 };
                return newsitemdto;
            }

2 Comments

Thanks for the replies, but I think I would need Web API 2 for either of these?
I do not think you need Web API 2 for this solution. All you are doing is creating a class(NewsItemDto) and putting only the data you need from NewsItem in this class. That way you end up with a simpler json object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.