批量更新时,Google电子表格API C#缺少资源版本ID

时间:2013-12-30 14:22:27

标签: c# google-api google-spreadsheet-api

我正在尝试使用电子表格api C#v2.2.0.0以这种方式批量更新空单元格:

foreach (var csvline in csv)
{
          var csvlineParsed = csvline.Split(';');
          for (uint index = 0; index < csvlineParsed.Length; index++)
          {
                var cellEntry = new CellEntry(i, index + 1, csvlineParsed[index]);
                cellFeed.Insert(cellEntry);

                var cell = new CellEntry(i, index + 1);
                cell.Id = new AtomId(string.Format("{0}/{1}", cellFeed.Self, "R" + i + "C" + index + 1));
                cell.InputValue = csvlineParsed[index];
                cell.BatchData = new GDataBatchEntryData("R" + cell.Row + "C" + cell.Column, GDataBatchOperationType.update);
                batchRequest.Entries.Add(cell);*/

          }
          i++;
}

var batchResponse = (CellFeed) _service.Batch(batchRequest, new Uri(cellFeed.Batch));

但我有“缺少资源版本ID”错误

4 个答案:

答案 0 :(得分:4)

我解决这个问题的另一种方法是添加额外的HTTP标头

If-Match: *

哪个说覆盖任何东西。

答案 1 :(得分:1)

我遇到了类似的问题。我们最终将CellEntry上的Etag属性设置为*,这允许更新通过。我确定它基本上是让它覆盖单元格中值中的任何值,但如果你发生了很多并发进程/更新,这只是一个问题。

我们抓住了CellFeed并直接从中获取了CellEntry,并进行了修改,包括设置Etag。之后,我们在其上调用了Publish(),它对所有标记为脏的条目进行批量请求,这些条目会在您更改内容时自动发生,或者您可以手动设置entry.Dirty = True

一些粗略的代码来解释我们做了什么,这只是将第一行中的单元格设置为values中的字符串,cellQuery是一个获取您想要使用的单元格的CellQuery。 / p>

CellFeed cellFeed = spreadsheetService.Query(cellQuery);
int i = 1;
foreach (string value in values)
{
   CellEntry entry = cellFeed[1, i++];
   entry.InputValue = value;
   entry.Etag = "*";
}

cellFeed.Publish();

您可能会发出自己的批量请求,并将实体Etag设置为*并获得相同的结果,但我发现Publish()方法更容易使用。

答案 2 :(得分:1)

因为我个人在确定如何应用之前建议的答案时遇到了一些麻烦。我到互联网的末端试图找到如何设置额外的标题(If-Match:*)

所以我会把这个留给你。

在我的Java应用程序中,这样做:

    service.setHeader("If-Match", "*")

在我的.NET应用程序中,它完成了:

    ((GDataRequestFactory)service.RequestFactory).CustomHeaders.Add("If-Match: *");

我希望这会挽救一些正在寻找这个的人(尤其是那个我花费数小时试图找到的.NET版本)。

  • AydinE

答案 3 :(得分:0)

A有同样的问题,根据文档(https://developers.google.com/google-apps/spreadsheets/?hl=fr-FR&csw=1#updating_multiple_cells_with_a_batch_request),

首先,你必须得到实体,不能像我想的那样“简单”。

private static Dictionary<String, CellEntry> GetCellEntryMap(
    SpreadsheetsService service, CellFeed cellFeed, List<CellAddress> cellAddrs)
{
  CellFeed batchRequest = new CellFeed(new Uri(cellFeed.Self), service);
  foreach (CellAddress cellId in cellAddrs)
  {
    CellEntry batchEntry = new CellEntry(cellId.Row, cellId.Col, cellId.IdString);
    batchEntry.Id = new AtomId(string.Format("{0}/{1}", cellFeed.Self, cellId.IdString));
    batchEntry.BatchData = new GDataBatchEntryData(cellId.IdString, GDataBatchOperationType.query);
    batchRequest.Entries.Add(batchEntry);
  }

  CellFeed queryBatchResponse = (CellFeed)service.Batch(batchRequest, new Uri(cellFeed.Batch));

  Dictionary<String, CellEntry> cellEntryMap = new Dictionary<String, CellEntry>();
  foreach (CellEntry entry in queryBatchResponse.Entries)
  {
    cellEntryMap.Add(entry.BatchData.Id, entry);
    Console.WriteLine("batch {0} (CellEntry: id={1} editLink={2} inputValue={3})",
        entry.BatchData.Id, entry.Id, entry.EditUri,
        entry.InputValue);
  }

  return cellEntryMap;
}