Google Drive API上传命令ResponseBody始终为空C#

时间:2019-02-18 21:31:45

标签: c# raspberry-pi google-drive-api

我正在使用由Raspberry Pi驱动的系统。作为此过程的一部分,我正尝试从Pi将文本文件上传到我的Google驱动器。作为第一个测试,我有一个UWP应用程序来创建一个温度和湿度数据的文本文件,然后尝试将其上传。

到上载命令时,什么都没有发生。不会引发异常,但不会上传任何文件。我已经在网上搜索了很多死胡同,但是没有错误,我真的不知道从哪里开始找出为什么文件没有上传的原因。我按照Google的指示进行操作,就像我说的那样,没有任何异常可以解决,它只是行不通的。任何建议都将受到欢迎,因为我已经花了很长时间在Google上搜索,但一无所获。

这是uwp应用程序xaml页面背后的代码的精髓(如果您需要,我可以将整个项目发送给您)。我没有在下面的代码中包含几个方法,因为只是方法StoreValues()使我暂时感到困惑。这是项目的第一次迭代,没有引发错误。

public sealed partial class MainPage : Page
{
    static string[] Scopes = { DriveService.Scope.Drive };
    static string AppName = "Drive API .NET Quickstart";
    static string fileName = "Environmental_Data";
    static string fileExtension = ".txt";
    private const int DHTPIN = 4;
    private IDht dht = null;
    private GpioPin dhtPin = null;
    private DispatcherTimer sensorTimer = new DispatcherTimer();
    private int counterWrite = 0;
    private int counterStore = 0;
    //the number on the end of the filename that will be incremented each time a file is produced.
    //TODO remove old files and reset counter periodically
    private int fileId = 1;
    //read values every this many seconds
    private int readInterval = 1;
    //write a new line to the file every this many readings
    private int writeCollectionSize = 2;
    //send file to cloud every this many lines
    private int storeCollectionSize = 4;

    private StorageFolder Folder = ApplicationData.Current.LocalFolder;
    public List<Environment> Readings;
    public StorageFile File1;

    public MainPage()
    {
        InitializeComponent();
        InitializeLocalFiles(fileId);
        InitializePi();
    }

    private async void InitializeLocalFiles(int fileId)
    {
        try
        {
            //make a new target file to save our data to
            var newFile = $"{fileName}_{fileId.ToString()}{fileExtension}";
            File1 = await Folder.CreateFileAsync(newFile, CreationCollisionOption.ReplaceExisting);
            File1 = await Folder.GetFileAsync(newFile);
            //let a human know where the first file is
            Debug.WriteLine(File1.Path);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("error incountered in InitializeLocalFiles: {0}", ex.Message);
        }
    }
    private void InitializePi()
    {
        try
        {
            //set up the pins etc
            dhtPin = GpioController.GetDefault().OpenPin(DHTPIN, GpioSharingMode.Exclusive);
            dht = new Dht11(dhtPin, GpioPinDriveMode.Input);

            //This is what the environment class looks like: public class Environment 
            //{ public decimal Temperature; public decimal Humidity; public DateTime DateTime; }
            Readings = new List<Environment>();
            sensorTimer.Interval = TimeSpan.FromSeconds(readInterval);

            //add the tick to the clock and set it going
            sensorTimer.Tick += sensorTimer_Tick;
            sensorTimer.Start();

            //initialise the app
            temperatureMeter.Value = "OFF";
            humidityMeter.Value = "OFF";
        }
        catch (Exception ex)
        {
            Debug.WriteLine("error incountered in InitialisePi: {0}", ex.Message);
        }
    }

    private void sensorTimer_Tick(object sender, object e)
    {
        try
        {
            //every tick of the clock, we will read the sensor to get new values
            readSensor();

            //if we got to the end of the write collection, then it is time to aggregate the figures and write a line to the local file
            if (counterWrite == writeCollectionSize)
            {
                counterWrite = 0;
                Readings.AggregateListToCSV(File1);
                //clear the list of readings ready for the next tick
                Readings.Clear();
            }
            //if we got to the end of the store collection, it's time to send the local file on a trip around the world
            if (counterStore == storeCollectionSize)
            {
                counterStore = 0;
                StoreValues(File1);
                //rather than deleting the file, we will make a new one for the next go-round
                fileId += 1;
                InitializeLocalFiles(fileId);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("error incountered in sensorTimer_Tick: {0}", ex.Message);
        }
    }
    private async void StoreValues(StorageFile file)
    {
        try
        {
            UserCredential credential;

            string cred = @"{""installed"":{""client_id"":""* **REDACTED FOR FORUM QUESTION ***"",""redirect_uris"":[""urn:ietf:wg:oauth:2.0:oob"",""http://localhost""]}}";
            byte[] byteArray = Encoding.UTF8.GetBytes(cred);

            //I'm using credentials stored in memory, but you could use a json file
            using (var stream =
                 //new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
                 new MemoryStream(byteArray))
            {
                //TODO find out why I have to copy the token.json file every time to the app folder - for some reason it does not copy over even though set to Copy Always
                string credPath = "token.json";
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    Scopes,
                    "user",
                    CancellationToken.None,
                    new FileDataStore(credPath, true)).Result;

            }

            //set up the stuff that the Google Drive seems to require. I don't pretend to understand this bit
            DriveService service = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = AppName,
            });

            service.HttpClient.Timeout = TimeSpan.FromMinutes(100);
            var fileMetadata = new Google.Apis.Drive.v3.Data.File()
            {
                Name = "My Report",
                MimeType = "application/vnd.google-apps.file"
            };

            FilesResource.CreateMediaUpload request;

            //using (var stream = new FileStream(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            using (var stream = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                request = service.Files.Create(fileMetadata, stream, "text/plain");
                request.Fields = "id";
                await request.UploadAsync();
            }
            //request.ResponsBody is always NULL - why??
            var responseFile = request.ResponseBody;
            //this line causes an error "attempted to read or write protected memory"
            if (responseFile == null)
            {
                Debug.WriteLine($"** ERROR **    File {fileName}_{(fileId - 1).ToString()}{fileExtension} could not be uploaded.");
            }
            else
            {
                Debug.WriteLine($"File ID: {responseFile.Id.ToString()}");
            }
        }
        catch(Exception ex)
        {
            Debug.WriteLine("error incountered in StoreValues: {0}", ex.Message);
        }
    }
}

这将产生一个如下所示的调试输出(显示了一个片段)

 ....
C:\Data\Users\DefaultAccount\AppData\Local\Packages\e50d180b-3aea-4119-a4ff-72592c8ac7b5_4j4qdv46jwqvm\LocalState\Environmental_Data_6.txt
Lines ready to write: 1    |     Lines ready to store: 1
** ERROR **    File Environmental_Data_5.txt could not be uploaded.
Lines ready to write: 2    |     Lines ready to store: 2
18.9,10.0,2/16/2019 7:32:16 AM

Lines ready to write: 1    |     Lines ready to store: 3
Lines ready to write: 2    |     Lines ready to store: 4
18.9,9.9,2/16/2019 7:32:19 AM

C:\Data\Users\DefaultAccount\AppData\Local\Packages\e50d180b-3aea-4119-a4ff-72592c8ac7b5_4j4qdv46jwqvm\LocalState\Environmental_Data_7.txt
** ERROR **    File Environmental_Data_6.txt could not be uploaded.
Lines ready to write: 1    |     Lines ready to store: 1
Lines ready to write: 2    |     Lines ready to store: 2
18.9,10.1,2/16/2019 7:32:22 AM

Lines ready to write: 1    |     Lines ready to store: 3
Lines ready to write: 2    |     Lines ready to store: 4
The thread 0xfac has exited with code 0 (0x0).
Lines ready to write: 1    |     Lines ready to store: 1
18.9,10.05,2/16/2019 7:32:25 AM

C:\Data\Users\DefaultAccount\AppData\Local\Packages\e50d180b-3aea-4119-a4ff-72592c8ac7b5_4j4qdv46jwqvm\LocalState\Environmental_Data_8.txt
** ERROR **    File Environmental_Data_7.txt could not be uploaded.
Lines ready to write: 2    |     Lines ready to store: 2
...

我相信我已经拥有所有的凭证等-每次部署时,我都必须将根据凭证生成的token.jsn文件复制到pi上,但是似乎所有这些都可以正常连接。 / p>

虽然我开始对wpf的开始有了一些了解,但这全都超出了我的理解范围,经过3周的尝试来解决这个问题后,我真的走到了尽头束缚-任何建议都很棒。

0 个答案:

没有答案