Google spreadsheets API C# missing resource version id on batch update

对着背影说爱祢 提交于 2019-12-05 21:43:21

Another way I solved this is through adding an additional HTTP header

If-Match: *

Which says overwrite anything.

We ran into a similar issue where I work. We wound up setting the Etag property on the CellEntry to * which allows the update to pass through. I'm sure it basically is letting it overwrite any value that was in the value in the cell but that's only an issue if you have a lot of concurrent processes/updates happening.

We grabbed the CellFeed and got the CellEntry's directly from it, and made our modifications including setting the Etag. After that we called Publish() on it which does a batch request of all the entries that are marked dirty, which happens automatically when you change something on them, or you can manually set entry.Dirty = True.

Some rough code to explain what we did, this just sets the cells in the first row to the strings in values, cellQuery is a CellQuery that gets the cells you want to work with.

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();

You could probably make a batch request of your own and set the entities Etag to * and get the same results, but I find the Publish() method much easier to work with.

Because I personally had some trouble figuring out how to apply the previously suggested answers. I went to the ends of the internet to try to find how to set the extra header (If-Match: *)

So I will leave this here for you.

In my Java application this was done doing:

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

In my .NET application it was done doing:

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

I hope this will save some of you that were looking for this (Especially the one for the .NET version which I literally spent hours trying to find) some time.

  • AydinE

A had the same problem, and according to the documentation (https://developers.google.com/google-apps/spreadsheets/?hl=fr-FR&csw=1#updating_multiple_cells_with_a_batch_request),

First of all you have to get the entities, cannt do it as "simple" as you are trying I think.

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!