0

不确定我是否以正确的方式问这个问题。但是我正在为我的大学做一个带有 CRM 系统和 API 的项目。现在我找到了 Flurl 来帮助我完成我的 HTTP 请求。它工作得很好,直到我尝试将我的免费开发人员帐户的所有帐户都添加到销售人员(我添加了一些测试帐户)。我收到的 JSON 是这样的:

{ 
"objectDescribe": {
"activateable": false,
"createable": true,
"custom": false,
"customSetting": false,
"deletable": true,
"deprecatedAndHidden": false,
"feedEnabled": true,
"hasSubtypes": false,
"isSubtype": false,
"keyPrefix": "001",
"label": "Account",
"labelPlural": "Accounts",
"layoutable": true,
"mergeable": true,
"mruEnabled": true,
"name": "Account",
"queryable": true,
"replicateable": true,
"retrieveable": true,
"searchable": true,
"triggerable": true,
"undeletable": true,
"updateable": true,
"urls": {
  "compactLayouts": "/services/data/v39.0/sobjects/Account/describe/compactLayouts",
  "rowTemplate": "/services/data/v39.0/sobjects/Account/{ID}",
  "approvalLayouts": "/services/data/v39.0/sobjects/Account/describe/approvalLayouts",
  "defaultValues": "/services/data/v39.0/sobjects/Account/defaultValues?recordTypeId&fields",
  "listviews": "/services/data/v39.0/sobjects/Account/listviews",
  "describe": "/services/data/v39.0/sobjects/Account/describe",
  "quickActions": "/services/data/v39.0/sobjects/Account/quickActions",
  "layouts": "/services/data/v39.0/sobjects/Account/describe/layouts",
  "sobject": "/services/data/v39.0/sobjects/Account"
}  
},  
"recentItems": [
{
  "attributes": {
    "type": "Account",
    "url": "/services/data/v39.0/sobjects/Account/0015800000it9T3AAI"
  },
  "Id": "0015800000it9T3AAI",
  "Name": "Test 5"
},
{
  "attributes": {
    "type": "Account",
    "url": "/services/data/v39.0/sobjects/Account/0015800000it8eAAAQ"
  },
  "Id": "0015800000it8eAAAQ",
  "Name": "Test 4"
},
{
  "attributes": {
    "type": "Account",
    "url": "/services/data/v39.0/sobjects/Account/0015800000it8dbAAA"
  },
  "Id": "0015800000it8dbAAA",
  "Name": "Test 3"
},
{
  "attributes": {
    "type": "Account",
    "url": "/services/data/v39.0/sobjects/Account/0015800000it8dHAAQ"
  },
  "Id": "0015800000it8dHAAQ",
  "Name": "Test 2"
},
{
  "attributes": {
    "type": "Account",
    "url": "/services/data/v39.0/sobjects/Account/0015800000it8ciAAA"
  },
  "Id": "0015800000it8ciAAA",
  "Name": "Test 1"
}  
]
}

我收到的错误如下:

Request to https://eu6.salesforce.com/services/data/v39.0/sobjects/Account/ failed. 
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IEnumerable`1[InHollandCRMAPI.Models.AccountItem]' 
because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object.
JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'objectDescribe', line 1, position 18.

我还在这里找到了这个链接: Parsing from json to object using FLURL

但我似乎无法用我的模型重新创建它:

public class AccountItem : ICRMItem
{
    public Describe[] ObjectDescribe { get; set; }
    public List<Recent> recentItems { get; set; }

    public class Recent
    {
        public Attributes[] Attributes { get; set; }
        public string Id { get; set; }
        public string Name { get; set; }
    }

    public class Describe
    {
        public bool activateable { get; set; }
        public bool createable { get; set; }
        public bool custom { get; set; }
        public bool customSetting { get; set; }
        public bool deletable { get; set; }
        public bool deprecatedAndHidden { get; set; }
        public bool feedEnabled { get; set; }
        public bool hasSubtypes { get; set; }
        public bool isSubtype { get; set; }
        public string keyPrefix { get; set; }
        public string label { get; set; }
        public string labelPlural { get; set; }
        public bool layoutable { get; set; }
        public bool mergeable { get; set; }
        public bool mruEnabled { get; set; }
        public string name { get; set; }
        public bool queryable { get; set; }
        public bool replicateable { get; set; }
        public bool retrieveable { get; set; }
        public bool searchable { get; set; }
        public bool triggerable { get; set; }
        public bool undeletable { get; set; }
        public bool updateable { get; set; }
        public Urls[] urls { get; set; }
    }
}

最后这就是我的代码中 de Deserialize 的方式

                    response = request.GetAsync();
                    responseData = await response.ReceiveJson<T>().ConfigureAwait(true);

编辑请求进来的我的控制器类:

[HttpGet("{CRM}")]
    public IEnumerable<ICRMItem> Get(string CRM)
    {
        if(CRM == "SalesForce")
        {
            ICRMService AccountGetAll = new AccountService();
            var Account = AccountGetAll.With<AccountItem>().GetAll().ResponseData();
            return Account;
        }
}

在@Todd Menier 他的改变之后

正如我在托德的消息中的回应,可耻的是它并没有起到作用。我仍然收到此异常消息。

Request to https://eu6.salesforce.com/services/data/v39.0/sobjects/Account/ ailed. Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type
'System.Collections.Generic.IEnumerable`1[InHollandCRMAPI.Models.AccountItem]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. 
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) 
that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. 
Path 'objectDescribe', line 1, position 18.

编辑

Todd Menier 向我询问了我的代码所采用的路径,所以它是:

在我打完电话后,它进入我的控制器

            ICRMService AccountGetAll = new AccountService();
            var Account = AccountGetAll.With<AccountItem>().GetAll().ResponseData();
            return Account;

在它进入我的服务之后:

    public ICRMServiceWithResource<T> With<T>(bool beta = false) where T : ICRMItem
    {
        var Uri = "https://eu6.salesforce.com/services/data/v39.0/";
        return new SalesForceServiceWithResource<T>()
        {
            Resource = Resources.Resources.GetResource<T>(),
            Uri = Uri
        };
    }

然后它得到资源

  public class Resources
{
    public const string Accounts = "sobjects/Account/";

    public static string GetResource<T>() where T : ICRMItem
    {
        var type = typeof(T);

        if (type == typeof(AccountItem)) return Accounts;

它进入了我的 GetAll 函数

    public ICRMResponse<IEnumerable<T>> GetAll()
    {
        return Get<IEnumerable<T>>();
    }

如您所见,它转到了一个 get 函数

    private ICRMResponse<TOut> Get<TOut>(string id = "")
    {
        return DoRequest<TOut>(Resource + id, "GET", null).Result;
    }

从它进入 DoRequest 的位置:

public async Task<ICRMResponse<T>> DoRequest<T>(string url, string method, object body)
        {
            ICRMResponse<T> result;
            try
            {
                GetCRM(AppConfig.Key);
                var request = Authorise(url);
                Task<HttpResponseMessage> response;
                T responseData;
                switch (method.ToLower())
                {
                    case "post":
                        if (body == null)
                        {
                            throw new ArgumentNullException("body");
                        }
                        response = request.PostJsonAsync(body);
                        responseData = await response.ReceiveJson<T>().ConfigureAwait(false);
                        break;
                    case "get":
                        response = request.GetAsync();
                        responseData = await response.ReceiveJson<T>().ConfigureAwait(true);
                    break;

从哪里中断并将消息显示为之前的状态

我会在 16:00 GMT+1 左右回来查看,否则周二早上希望我给了你你需要的一切

4

2 回答 2

0

在您的 C# 模型中,urls是一个数组,但它不是 JSON 表示中的数组;它是一个对象。

你没有发布你的Urls类的定义,但我猜它看起来像这样:

public class Urls
{
    public string compactLayouts { get; set; }
    public string rowTemplate { get; set; }
    public string approvalLayouts { get; set; }
    public string defaultValues { get; set; }
    public string listviews { get; set; }
    public string describe { get; set; }
    public string quickActions { get; set; }
    public string layouts { get; set; }
    public string sobject { get; set; }
}

JSON 返回一个看起来像这样的对象,而不是它们的集合。因此,在您的Describe类中,只需删除数组并像这样定义它:

public Urls urls { get; set; }

更新:

起初我没有看到这一点,但objectDescribeand也有类似的问题attributes。这些也不是数组,所以不要在 C# 模型中以这种方式定义它们。以下是所有更改的摘要:

public class AccountItem : ICRMItem
{
    public Describe ObjectDescribe { get; set; }
    ...

    public class Recent
    {
        public Attributes Attributes { get; set; }
        ...
    }

    public class Describe
    {
        ...
        public Urls urls { get; set; }
    }
}
于 2017-04-05T14:19:19.530 回答
-1

Soo,我刚刚修复了错误。试图获取所有帐户的列表。但是销售人员已经为您列出(部分)帐户。

问题IEnumerable出在GetAll()功能上(对于大多数 CRM 系统都非常有效),但如果您想完成此操作,您需要将其更改IEnumerable<T>为 just T,这将是 SalesForce 的快速修复

我的下一步是生成一个包含所有帐户信息的帐户列表(就像大多数 GetAll 使用 CRM API 一样)。

TL;博士

public ICRMResponse<IEnumerable<T>> GetAll() { return Get<IEnumerable<T>>(); }

应该

public ICRMResponse<T> GetAll() //Technicly isn't a GetAll But a Get { return DoRequest<T>(Resource, "GET", null).Result; }

这是对这篇文章的修复,不是对我最终愿望的修复,但我会关闭这个主题,因为否则我们会偏离主题

于 2017-04-12T09:42:14.847 回答