【问题标题】:How best to get MVC web api to return data for Angular to use如何最好地让 MVC Web api 返回数据以供 Angular 使用
【发布时间】:2016-01-06 06:01:03
【问题描述】:

我正在开始使用 Angular 和 ASP Web Api,但遇到了困难,真的很欢迎一些帮助。

我正在开发一个网站,该网站有一个新闻页面,以及主页上最近项目的新闻提要。它使用 angular 和我手动更新的简单 JSON 文件,一切正常。我想编写一个 MVC4 Web 应用程序来允许用户更新新闻和一个用于 Angular 连接的 Web api。

我已经开始了一个试验项目,并且连接到 SQL Server 的记录的 CRUD 的 Web 应用程序项目一切正常。我已经构建了一个基于标准 VS 模板的 web api,它在调试时可以在浏览器中看到 JSON 数据,但是我无法工作,我不知道如何调试它任何进一步。我的模型在两个表之间有关系,这似乎使返回的 JSON 非常复杂。我想知道最好的方法,我是否需要修改我的控制器以只返回我想要的数据,或者修改数据在 global.asax 中的返回方式?谢谢。

我的模特:

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

我的控制器:

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 返回:

[{"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"}]

角度:

// 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>

【问题讨论】:

    标签: asp.net json angularjs asp.net-mvc-4 asp.net-web-api


    【解决方案1】:

    如果您只想从模型返回特定数据,您可以创建一个仅包含您需要的数据的 DTO 对象,然后将您想要的值分配给 DTO。

    所以在你的控制器中是这样的:

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

    【讨论】:

    • 感谢您的回复,但我想我需要 Web API 2 来处理其中的任何一个?
    • 我认为您不需要 Web API 2 来实现此解决方案。您所做的只是创建一个类(NewsItemDto)并仅将您需要的来自 NewsItem 的数据放入该类中。这样你最终会得到一个更简单的 json 对象。
    【解决方案2】:

    我通常有我的控制器返回类型 IHttpActionResult:

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

    然后你的 http 回调中的“数据”对象包含 json。

    【讨论】:

    • IHttpActionResult 仅在 Web API 2.x 及更高版本中受支持。
    • 返回对象的类型无关紧要,除了操作已经返回有效的 JSON。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 2011-01-20
    • 2014-01-14
    • 2011-10-31
    • 2014-04-04
    • 2013-04-30
    相关资源
    最近更新 更多