【问题标题】:Angular receives String as array?Angular接收字符串作为数组?
【发布时间】:2014-11-04 10:45:00
【问题描述】:

我正在玩弄 AngularJS 和 ASP.Net 的 Web API 一起工作。我在 API 中有一个非常简单的 TestController:

public class TestController : ApiController {
    [HttpGet]
    public String Ping() {
        return "Pong";
    }
}

在 Chrome 中,我可以转到 http://localhost/api/Test/Ping,fiddler 显示一个简单的 "Pong" 结果,浏览器显示:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Pong</string>

回到 Angular JS,我设置了一个工厂来调用 Ping 函数:

app.factory('API', ['$resource', function ($resource) {
    return {
        Ping: function () {
            var result = $resource('api/Test/Ping', {}, { get: { method: 'GET' }, isArray: false });
            return result.get();
        }
    };
}]);

还有一个超级简单的控制器:

app.controller('MyCtrl', [ '$scope', 'API', function ($scope, API) {
    $scope.CallTest = function () {
        API.Ping().$promise.then(function (response) {
            alert(response);
        });
    }
}]);

当我单击CallTest 绑定的按钮时,它会进行调用,API 会按原样返回 Pong,但返回对象并不完全符合我的预期。响应是一个奇怪的对象:

{
    0: """,
    1: "P",
    2: "o",
    3: "n",
    4: "g",
    5: """,
    $promise: {...},
    $resolved: true
}

我没有收到任何错误,并且在语法上一切正常。然而,我希望response 是一个字符串,特别是因为我在我的API 工厂中将isArray 设置为false。我相信角度必须返回一个“资源”,上面有一个$promise$resolved,所以我现在明白它可能不会那样工作。除了在 WebAPI 中制作一个简单的包装器以将字符串作为模型上的参数返回之外,是否有可用的客户端选项以便 response 可以包含普通字符串而不是这个伪数组?比如response.data 之类的?

编辑:当我从浏览器请求时,Accept 标头包含:

text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

这会导致上面的 XML 结果。当 Angular 请求相同的 url 时,Accept 标头包含:

application/json, text/plain, */*

这导致响应的内容只是"Pong"

【问题讨论】:

  • 你为什么不在你的 web api 中使用 JSON.net 并将 json 或 JObject 返回到 angular?
  • @Owen 我可以将它包装成 JSON、XML、SOAP 等任何东西,但是一个简单的字符串应该是最容易正确解析的东西。
  • 根据我的发现,将文字转储到 $resource 会将文字转储为字符串数组。我在将值传递给 $resource 以用作参数时发生了这种情况。如果该值不是分配的变量,则将字符串分解为一个数组。对我来说,用文字的值分配一个变量是解决这个问题的最快方法。从我的 Web API 获取数据,我只传递 JObjects。
  • 这是我在 gitHub 提交上发布的地方,我发现了这一点。 github.com/angular/angular.js/commit/…

标签: angularjs asp.net-web-api


【解决方案1】:

如文档中所述,$resource 是一个创建资源对象的工厂,可让您与 RESTful 服务器端数据源进行交互

在您的情况下,您并没有尝试与正确的 RESTful 数据源进行交互,因此该行为看起来很奇怪。

在您拥有适当的 RESTful 数据源并且只想访问 API 端点并检索简单响应(例如字符串)之前,您应该使用 $http service

$http.get('api/Test/Ping').success(function (data) {...})...

例如:

app.factory('API', ['$http', function ($http) {
    return {
        Ping: function () {
            return $http.get('api/Test/Ping');
        }
    };
}]);

app.controller('MyCtrl', ['$scope', 'API', function ($scope, API) {
    $scope.CallTest = function () {
        API.Ping().success(function (data) {
            alert(data);
        });
    };
}]);

【讨论】:

  • 好点。自从我开始使用 $resource 后,我就完全不使用 $http。这是一种需要的情况。
【解决方案2】:

如 Angular 存储库 here 中所述,当 shallowClearAndCopy 迭代键时,字符串文字被转换为对象。就我而言,将字符串文字传递给 $resource 会导致文字变成字符数组。我能够解决这个问题的第一种方法是将文字分配给一个变量并传递变量。

api.Trip.get(data.token) - Incorrect
api.Trip.get({token: data.token}) - Correct.

鉴于您来自 Web API,这很可能需要将您的响应作为 JObject 或 JToken 发送。我的 Web API 使用 Newtonsoft 的 JSON.net 库返回 JObject,而 Angular 还没有跳过一个节拍。

【讨论】:

    猜你喜欢
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    • 1970-01-01
    相关资源
    最近更新 更多