【问题标题】:Fetching data from Azure Cosmos DB in Flutter?在 Flutter 中从 Azure Cosmos DB 获取数据?
【发布时间】:2018-07-02 15:59:42
【问题描述】:

我编写了一个函数来使用 Flutter/Dart 中 Azure Cosmos 数据库中的查询来获取数据,但是它给出了错误:

response.body: {"code":"BadRequest","message":"Message: {\"Errors\":[\"The input content is invalid because the required properties - 'æ©; ' - are missing\"]}\r\nActivityId: f75a0c6e-2c8d-4f13-a020-6e3c13fa5458, Request URI: /apps/f4533d11-81e3-4512-b639-0f0475c10611/services/401c9130-a85e-46a6-8311-c2dc8e5070d6/partitions/b5d2a58d-1304-414b-92c7-10e7fa95f679/replicas/131768862196689298p, RequestStats: , SDK: Microsoft.Azure.Documents.Common/2.0.0.0"}

I/flutter ( 5284): response.status: 400

这是我的一段代码

 final response = await http.post(
  endpointResource,
  // Query
  body: query,
  // Post new message
  headers: {
    HttpHeaders.AUTHORIZATION: authToken,
    HttpHeaders.CONTENT_TYPE: "application/query+json",
    //'content-type': 'application/json',
    'Accept': 'application/json',
    //c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    'x-ms-version': '2017-02-22',
    'x-ms-date': date,
    'x-ms-documentdb-isquery': 'true',
    'x-ms-query-enable-crosspartition': 'true',
    'x-ms-documentdb-query-enable-scan': 'true', 
  },
);

我应该怎么做才能取回数据?

【问题讨论】:

    标签: azure flutter azure-cosmosdb


    【解决方案1】:

    我设法将代码 sn-p 从 Javascript 中的工作示例转换为 Dart。

    import 'dart:io';
    import 'dart:convert';
    import 'dart:async';
    import 'dart:core';
    import 'package:crypto/crypto.dart';
    import 'package:hex/hex.dart';
    
    class Cosmos{
      String documentDBMasterKey;
    
      Cosmos({this.documentDBMasterKey});
    
     Future queryCosmos({url, method, body}) async{
        String auth;
        String documentDBMasterKey = this.documentDBMasterKey;
        print("mastKey: $documentDBMasterKey");
    
        method = method.trim(); //GET, POST, PUT or DEL
        url = url.trim();
        String utcString = HttpDate.format(DateTime.now());
    
        print('RFC1123time: $utcString');
        print('request url = ' + url);
    
        String strippedurl =
            url.replaceAllMapped(RegExp(r'^https?://[^/]+/'), (match) {
          return '/';
        });
    
        print('stripped Url: $strippedurl');
    
        List strippedparts = strippedurl.split('/');
        int truestrippedcount = strippedparts.length - 1;
        print('$truestrippedcount');
    
      String resourceId;
      String resType;
    
        if (truestrippedcount % 2 != 0){
          print('odd');
          resType = strippedparts[truestrippedcount];
          print('$resType');
    
          if (truestrippedcount > 1){
            int  lastPart = strippedurl.lastIndexOf('/');
            resourceId = strippedurl.substring(1, lastPart);
            print('ResourceId: ' + resourceId); 
          }
        }
        else{
          print('even');
          resType = strippedparts[truestrippedcount -1];
          print('resType: $resType');
          strippedurl = strippedurl.substring(1);
          print('strippedurl $strippedurl');
          resourceId = strippedurl;
          print('ResourceId: ' + resourceId);
        }
    
      String verb = method.toLowerCase();
      String date = utcString.toLowerCase();
    
      Base64Codec base64 = const Base64Codec(); 
      var key = base64.decode(documentDBMasterKey); //Base64Bits --> BITS
      print('key = ${HEX.encode(key)}');
      print('masterKey = $documentDBMasterKey');
    
      String text = (verb ?? '').toLowerCase() + '\n' + 
                    (resType ?? '').toLowerCase() + '\n' +
                    (resourceId ?? '') + '\n' +
                    (date ?? '').toLowerCase() + '\n' +
                    '' + '\n';
    
      print('text: $text');
    
      var hmacSha256 = Hmac(sha256, key);
      List<int> utf8Text = utf8.encode(text);
      var hashSignature = hmacSha256.convert(utf8Text);
      String base64Bits = base64.encode(hashSignature.bytes);
    
    //Format our authentication token and URI encode it.
    var masterToken = "master";
    var tokenVersion = "1.0";
    auth = Uri.encodeComponent('type=' + masterToken + '&ver=' + tokenVersion + '&sig=' + base64Bits);
    print('auth= $auth');
    
      Map<String, String> headers = {
        'Accept': 'application/json',
        'x-ms-version': '2016-07-11',
        'Authorization': auth,
        'x-ms-date': utcString,
        'x-ms-documentdb-isquery' : 'true',
        'Content-Type' : 'application/query+json',
        'x-ms-documentdb-query-enablecrosspartition' : 'true',
      };
    
      Future<String> readResponse(HttpClientResponse response) {
      final completer = Completer<String>();
      final contents = StringBuffer();
      response.transform(utf8.decoder).listen((data) {
        contents.write(data);
      }, onDone: () => completer.complete(contents.toString()));
      return completer.future;
    }
    
      HttpClientRequest request;
      HttpClient httpClient = new HttpClient();
      if (method=='GET'){
        request = await httpClient.getUrl(Uri.parse(url));
      }
      else if(method=='POST'){
        request = await httpClient.postUrl(Uri.parse(url));
      }
      else if(method=='PUT'){
        request = await httpClient.putUrl(Uri.parse(url));
      }
      else if(method=='DEL'){
        request = await httpClient.deleteUrl(Uri.parse(url));
      }
        headers.forEach((key, value) {
          request.headers.set(key,value);
        });
    
        if(body != null) {
          request.add(utf8.encode(json.encode(body)));
        }
    
        HttpClientResponse aresponse = await request.close();
        httpClient.close();
      String aresponseString = await readResponse(aresponse);
      return jsonDecode(aresponseString); 
      }
    }
    

    只需使用你的 Cosmos 主密钥实例化类:

    Cosmos cosmos = Cosmos( documentDBMasterKey:'{your_cosmos_db_master_key}');

    通过调用 queryCosmos 方法查询 Cosmos Db。传递 'url'、'method' 和可选的 'body' 作为参数:

    // GET Example
        () async {
           Map<String, dynamic> get_dbs = await cosmos.queryCosmos(
             url: 'https://{your_base_url}.documents.azure.com:443/dbs', method: 'GET');
           print(get_dbs);
        }
    
    // POST Example (Query)
        () async {
        final Map<String, dynamic> body = {
          "query":
              "SELECT * FROM Faults f WHERE f.FaultId = @faultId",
          "parameters": [
            {"name": "@faultId", "value": 306000}
          ]
        };
        Map<String, dynamic> get_fault = await cosmos.queryCosmos(
            url:
                'https://{your_base_url}.documents.azure.com:443/dbs/{your_db}/colls/{your_collection}/docs',
            method: 'POST',
            body: body);
        print('Get fault $get_fault');
        }
    

    原始代码(JavaScript - 下载到 Postman 并检查 pre-req 脚本):https://github.com/MicrosoftCSA/documentdb-postman-collection

    我的代码(飞镖):https://github.com/fvarela/cosmos_db_dart

    【讨论】:

      【解决方案2】:

      我创建了一个 Dart 库来从 CosmosDB 中获取数据。例如,要从集合中获取文档,您只需调用此函数:

      import 'package:cosmosdb/cosmosdb.dart';
      
      void main() {
          final cosmosDB = CosmosDB(
            masterKey: '<YOUR_MASTER_KEY>',
            baseUrl: '<YOUR_BASE_URL>',
          );
          // get all documents from a collection
          final documents = cosmosDB.documents.list('<YOUR_DATABASE>', '<YOUR_COLLECTION>');
          print(documents);
      }
      

      GitHub:https://github.com/jonasfranz/cosmosdb

      包裹:https://pub.dev/packages/cosmosdb

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-16
        • 2019-12-30
        相关资源
        最近更新 更多