Ember Cli和ASP.NET webapi - 挂起数据

时间:2014-11-25 10:15:12

标签: json ember.js asp.net-web-api ember-data ember-cli

我有一个运行在localhost:4200上的Ember Cli项目和一个在localhost:56967上运行的asp.net webapi项目。两个项目分别运行良好:我可以启动我的Ember应用程序并测试几条路线,看起来很好,我可以访问我的api(例如:api / products),我看到了我的回复。

我遇到的问题是将这两件事互相挂钩。

适配器

 export default DS.RESTAdapter.extend({
      host: 'http://localhost:56967',
      namespace: 'api'
 });

我首先遇到了一些Cors问题,但我在我的Ember应用程序中修复了contentSecurityPolicy,并在我的Api上启用了Cors。

当我进入产品路线时,我可以看到对Api的请求被接受,Api回复了Json的回答。但是,我没有序列化模型,所以我可以在我的Ember应用程序中使用它。

这是我对Api的回应

  [{"ProductId":1,"Name":"Product 1","Description":"Category 1"},{"ProductId":2,"Name":"Product 2","Description":"Category 2"},{"ProductId":3,"Name":"Product 3","Description":"Category 3"}] 

产品的Ember模型

export default DS.Model.extend({
    name : DS.attr('string'),
    description: DS.attr('string')
});

产品的Asp.net模型:

public class Product
{
    public int ProductId { get; set; }
    [Required]
    public string Name { get; set; }
    public string Description { get; set; }
}

我知道我必须将Api响应序列化以使其成为可读的#34; Json为我的Ember App。现在的问题是:更改Api的格式是否更好?或者做一个好的序列化器?我如何制作序列化器?很难找到一些体面的教程。我尝试了这个,但那不起作用:

 export default DS.RESTSerializer.extend({
      primaryKey: 'productId'
  });

这是我得到的错误:

  Error while processing route: products No model was found for '0' Error: No model was found for '0'

修改 在尝试了建议的序列化程序和一些ASP.NET序列化程序后,我仍然无法使其工作。今天我找到了这个项目:http://jsonapi.codeplex.com/。它是一个Nuget包,可帮助您的ASP.NET API输出符合json.api标准。我立即使用了我的Ember数据。只需在休息适配器中添加正确的标题,如下所示:

 import DS from 'ember-data';

 export default DS.RESTAdapter.extend({
       host: 'http://localhost:57014',
       namespace: 'api',
       headers:{
          "Accept": "application/vnd.api+json"
        }
 });

在您的Asp.net模型中添加

[JsonObject(Title="product")]
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

}

它会将您的输出多元化为:

{
"products": [
    {
        "id": "1",
        "name": "Product 1",
        "description": "Category 1"
    },
    {
        "id": "2",
        "name": "Product 2",
        "description": "Category 2"
    },
    {
        "id": "3",
        "name": "Product 3",
        "description": "Category 3"
    }
]
}

它仍处于阿尔法州,但看起来很有希望。关于复数化的一个小注释:它只是将-s添加到您的模型名称中,需要牢记这一点。

1 个答案:

答案 0 :(得分:6)

主要问题是Asp Web API返回以下响应:

[
  {
    "ProductId":1,
    "Name":"Product 1",
    "Description":"Category 1"
  }
]

但是Ember Data希望服务器能够采用以下格式进行响应:

{
  "products": [
    {
      "productId": 1,
      "name": "Product 1",
      "description": "Category 1"
    }
  ]
}

您可以将Web API服务器的响应更新为Ember期望的格式,但在Ember中创建Serializer以将Asp Web API中的数据映射到Ember的格式会更容易。

wrote a detailed blog post解释了如何创建Ember Serializer来执行此映射。

请务必阅读博客文章,了解Serializer中发生的情况。但作为参考,我认为你的序列化器应该是这样的:

App.ProductSerializer = DS.RESTSerializer.extend({
  primaryKey: 'productId',

  extract: function(store, primaryType, payload, id, requestType) {
    if (payload.length) {
      for (var i = 0; i < payload.length; i++) {
        this.mapRecord(payload[i]); 
      }
    } else {
      this.mapRecord(payload);
    }

    payloadWithRoot = {};
    payloadWithRoot[primaryType.typeKey] = payload;

    this._super(store, primaryType, payloadWithRoot, id, requestType)
  },

  mapRecord: function(record) {
    for (var property in record) {
      var value = record[property];
      record[property.camelize()] = value;
      delete record[property];
      return record;
    }
  },

  serializeIntoHash: function(hash, type, record, options) {
    var recordJSON = record.toJSON();
    for (var property in recordJSON) {
      var value = recordJSON[property];
      hash[property.capitalize()] = value
    }
  }
});