0

I'm trying to update/replace a given text at a Google Docs Template.

The code i've tried so far:

DriveService service = GetDriveService();

var firstname = "Firstname";
var lastname = "Lastname";

BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest();

List<Request> requests = new List<Request>();

var repl = new Request();
var substrMatchCriteria = new SubstringMatchCriteria();
var replaceAlltext = new ReplaceAllTextRequest();
replaceAlltext.ReplaceText = firstname + "." + lastname;
substrMatchCriteria.Text = "vorname.nachname";
replaceAlltext.ContainsText = substrMatchCriteria;
repl.ReplaceAllText = replaceAlltext;

requests.Add(repl);
body.Requests = requests;


//Batch update Request requires 3 Parameters
DocumentsResource.BatchUpdateRequest bUpdate = new DocumentsResource.BatchUpdateRequest(service, body, "160NinGjrmshSga8fWkCFRwApV0FTL1BiJCidH7A1yFw");
bUpdate.Execute(); // The Exception is raised here

the DocumentsResource.BatchUpdateRequestrequires the following parameters: enter image description here

Following error occurs:

Google.GoogleApiException: "Not Found"

JsonReaderException: Error parsing NaN value. Path '', line 1, position 1.

Diese Ausnahme wurde ursprünglich bei dieser Aufrufliste ausgelöst:
Newtonsoft.Json.JsonTextReader.ParseNumberNaN(Newtonsoft.Json.ReadType, bool)
Newtonsoft.Json.JsonTextReader.ParseValue()
Newtonsoft.Json.JsonTextReader.Read()
Newtonsoft.Json.JsonReader.ReadForType(Newtonsoft.Json.Serialization.JsonContract, bool)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(Newtonsoft.Json.JsonReader, System.Type, bool)
Newtonsoft.Json.JsonSerializer.DeserializeInternal(Newtonsoft.Json.JsonReader, System.Type)
Newtonsoft.Json.JsonConvert.DeserializeObject(string, System.Type, Newtonsoft.Json.JsonSerializerSettings)
Google.Apis.Services.BaseClientService.DeserializeError(System.Net.Http.HttpResponseMessage)

I took the documentId from the Document path
enter image description here

Also the file is present using a files.list: enter image description here

What am I missing/doing wrong?

6
  • Willing to bet thats not the file id. Do a files.list from google drive api and find the corect file id. Also whats in GetDriveService Commented Feb 5, 2020 at 12:47
  • Added the files.list Request, which represents the given fileId Commented Feb 5, 2020 at 13:04
  • what line is it failing on somethings not found. Commented Feb 5, 2020 at 14:11
  • The method BatchUpdateRequest expects only two parameters - the request and the document Id, see here for a sample. Commented Feb 5, 2020 at 14:18
  • 1
    The third parameter is the OPTIONAL field writeControl. The only expected parameters are the documentId and the requests. I do not know what your variable service is but it is unlikely to be one of the required parameters. I assume that it is rather the resource to which you want to apply the batch request. Then it should be something like service.BatchUpdateRequest(body, "160NinGjrmshSga8fWkCFRwApV0FTL1BiJCidH7A1yFw"); I recommend you to test your request with the Try it API before C# implementation Commented Feb 7, 2020 at 11:30

1 Answer 1

2

First, you can try to generalize the GetService method, I did it because I use various scopes

public static object GetService(apiType api = apiType.GDrive)
    {
        UserCredential credential;
        
        string CSPath = HostingEnvironment.MapPath("~/MyFolder/");

        using (var stream = new FileStream(Path.Combine(CSPath, "client_secret.json"), FileMode.Open, FileAccess.Read))
        {

            string FolderPath = CSPath;

            string FilePath = Path.Combine(FolderPath, "DriveServiceCredentials.json");

            credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                Scopes,
                "user",
                CancellationToken.None,
                new FileDataStore(FilePath, true)
                ).Result;

        }
        
        if (api == apiType.GDocs)
        {
            DocsService docsService = new DocsService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = MyApplicationName,
            });
            return docsService;
        }
        else
        {
            DriveService driveService = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = MyApplicationName
            });
            return driveService;
        }

    }

then you can try something like this:

public static void EditDoc(string fileId, Dictionary<string, string> textToReplace)
    {
        DocsService service = (DocsService)GetService(apiType.GDocs);
        
        List<Request> requests = new List<Request>();

        foreach (var text in textToReplace)
        {
            var repl = new Request();
            var substrMatchCriteria = new SubstringMatchCriteria();
            var replaceAlltext = new ReplaceAllTextRequest();

            replaceAlltext.ReplaceText = text.Value;
            substrMatchCriteria.Text = text.Key;

            replaceAlltext.ContainsText = substrMatchCriteria;
            repl.ReplaceAllText = replaceAlltext;

            requests.Add(repl);
        }

        BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest { Requests = requests };
        
        service.Documents.BatchUpdate(body, fileId).Execute();

    }

I used this document as a reference https://developers.google.com/docs/api/how-tos/merge for some reason Google haven't translated it in C#...

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.