简体   繁体   中英

How best to get MVC web api to return data for Angular to use

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>

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.

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;
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM