Documentdb无法反序列化存储过程响应或将其转换为我定义的类型

时间:2016-06-23 20:48:10

标签: azure azure-cosmosdb

我的存储过程:(我是通过Azure Script Explorer创建的)

function GetAllResources() {
var collection = getContext().getCollection();

// Query documents and take 1st item.
var isAccepted = collection.queryDocuments(
    collection.getSelfLink(),
    'SELECT * FROM MultiLanguage as m',
    function (err, docs, options) {
        if (err) throw err;

        // Check the feed and if empty, set the body to 'no docs found', 
        // else take 1st element from feed
        if (!docs || !docs.length) getContext().getResponse().setBody('no docs found');
        else getContext().getResponse().setBody(JSON.stringify(docs));
    });

    if (!isAccepted) throw new Error('The query was not accepted by the server.');
}

可以从脚本浏览器成功执行sproc。

调用sproc的我的C#代码:

 public async Task<IHttpActionResult>  GetReources() {
        client = new DocumentClient(new Uri(ConfigurationManager.AppSettings["endpoint"]), ConfigurationManager.AppSettings["authKey"]);
        var collectionLink = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId);

        //var docs = await client.ReadDocumentFeedAsync(collectionLink, new FeedOptions { MaxItemCount = 10 });


        //var docs = from d in client.CreateDocumentQuery<Models.Resource>(collectionLink)
        //           select d;

        StoredProcedure storedProcedure = client.CreateStoredProcedureQuery(collectionLink).Where(c => c.Id == "GetAllResources").AsEnumerable().FirstOrDefault();

        Models.Resource docs = await client.ExecuteStoredProcedureAsync<Models.Resource>(storedProcedure.SelfLink);


        foreach (var d in docs) {
            Models.Resource a = new Models.Resource();
            a = docs;
            //a.id = d.id;
            //a.Scenario = d.Scenario;
            //a.Translations = d.Translations;
            //a.LastModified = d.LastModified;
            //a.ModifiedBy = d.ModifiedBy;
            //a.LastAccessed = d.LastAccessed;

            resources.Add(a);
        }



        return Ok(resources);
    }

首先,&#34; foreach ...&#34;喜欢说

  

foreach无法对Models.Resource类型的变量进行操作,因为它   不包含GetEnumerator的公共定义。

然后我尝试修改我的sproc只返回1个结果并删除foreach行,然后我得到错误说

  

无法反序列化存储过程响应或将其转换为类型   &#39; Models.Resource&#39;

我只想将存储过程的结果作为我定义的类(Models.Resource)返回。怎么做?

2 个答案:

答案 0 :(得分:1)

使用CreateStoredProcedureUri按名称获取sproc可能更简单,如下所示:

        const string endpoint = "https://your.service.azure.com:443/";
        const string authKey = "<your magic secret master key>==";

        var client = new DocumentClient(new Uri(endpoint), authKey);
        Uri sprocUri = UriFactory.CreateStoredProcedureUri("databaseName", "collectionName", "GetAllResources");

        var result = await client.ExecuteStoredProcedureAsync<string>(sprocUri);

上面的存储过程将查询(docs数组)的结果序列化为字符串,如果你保持这种方式,sproc的结果将是字符串,我猜你需要手动反序列化为对象。你可以更简单,只需从sproc返回文档并将结果作为对象(如Models.Resource []),序列化将自动发生。

如果更改sproc只返回一个doc(例如do __.response.setBody(docs[0])而Models.Resource代表一个项目,那么调用是正确的:

Models.Resource doc = await client.ExecuteStoredProcedureAsync<Models.Resource>(sprocUri);

此外,为了//查询文档并获取第1项,我不建议使用脚本,因为脚本具有运行JavsScript引擎的开销。当您进行批量操作(以优化网络流量)或具有在服务器上运行时有意义的业务逻辑时,脚本会启动。要获取第一项,您可以从客户端进行查询,如下所示:SELECT TOP 1 * FROM c。通常你会使用WHERE和ORDER BY子句。

github上有许多docdb示例,例如https://github.com/Azure/azure-documentdb-dotnet/tree/master/samples/code-samples/ServerSideScriptshttps://github.com/Azure/azure-documentdb-dotnet/tree/master/samples/code-samples/Queries

谢谢,
迈克尔

答案 1 :(得分:0)

好的,让我们确保我们在同一页上。

我正在使用与上面相同的sproc。 我正在使用这样的客户端代码:

    class Models
    {
        // This would have more properties, I am just using id which all docs would have.
        public class Resource
        {
            [JsonProperty("id")]
            public string Id { get; set; }
        }
    }

    public async Task<IHttpActionResult> GetResources()
    {
        const string endpoint = "https://myservice.azure.com:443/";
        const string authKey = "my secret key==";

        var client = new DocumentClient(new Uri(endpoint), authKey);
        Uri sprocUri = UriFactory.CreateStoredProcedureUri("db", "c1", "GetAllResources");

        var serializedDocs = await client.ExecuteStoredProcedureAsync<string>(sprocUri);
        Models.Resource[] resources = JsonConvert.DeserializeObject<Models.Resource[]>(serializedDocs);

        return Ok(resources);
    }

工作正常。这是你在做什么?