From the client I send an Ajax request to the server expecting a return.
$.ajax({
type: "POST",
url: "RespuestaajaxL.aspx/RespuestaajTask",
contentType: "application/json; charset=utf-8",
data: '{"parametro":"funcion","valor":"ActualizarArchivoDrive","tabla":"' + datosserver.nombrearchivo + '","campo":"' + datosserver.extensionarchivo + '","criterio":"' + datosserver.nombrearchivosinext + '","v1":"' + datosserver.extensionarchivoO + '","v2":"' + datosserver.idFile + '","v3":"' + datosserver.idFolder + '","v4":"","v5":"","v6":"","v7":"","v8":""}',
dataType: "json",
success: function (devolucion) {
if (devolucion.d) {
alert("Actualizado el archivo en Drive");
}
},
error: function (req, status, error) {
alert("No hubo respuesta desde el servidor. Prueba otra vez.");
}
});
The call is successful. In a routine already on the server, an update is performed of a file located in Google Drive. This update is carried out successfully but the response is not returned to the client. The process returns nothing to the client.
I have checked by reducing the code to the minimum, and then adding a new line back each time. The return to the client was always produced except when the line was reached:
var result = await updateRequest.UploadAsync(CancellationToken.None);
From a module from which I receive the Ajax request I execute the function that updates the file in Drive.
public static Task<string> RespuestaajTask(string parametro, string valor, string tabla, string campo, string criterio, string v1,
string v2, string v3, string v4, string v5, string v6, string v7, string v8)
{
try
{
if (parametro == "funcion")
{
if (valor == "ActualizarArchivoDrive")
{
return Cp.ActualizarArchivoDrive(tabla, campo, criterio, v1, v2, v3);
}
}
return null;
}
catch (Exception exc) {
string st = exc.Message;
}
return null;
}
The update of the Google Drive file was carried out using the following method:
public async Task<string> ActualizarArchivoDrive(string nombrefile, string extension, string nombrefilesinext, string extensionO, string idFile, string idFolder)
{
try
{
string extGuardar = (extension != extensionO ? "jpg" : extensionO);
Google.Apis.Drive.v3.DriveService ds = CodigoGeneral.Globales.gds;
string filePath = (string)HttpContext.Current.Server.MapPath("~") + "google/archivoseditados/" + nombrefilesinext + "." + extGuardar;
var updateFileBody = new Google.Apis.Drive.v3.Data.File()
{
Name = nombrefile
};
await Ue(filePath, idFile, "image/jpeg", updateFileBody, ds);
}
catch (Exception ee)
{
string ss = ee.Message;
}
return "Finalizado";
}
As you can see, the previous method calls the following method with await:
public async Task Ue(string filePath, string fileId, string MIME, Google.Apis.Drive.v3.Data.File updateFileBody, Google.Apis.Drive.v3.DriveService ds)
{
try
{
using (var uploadStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
// Update the file id, with new metadata and stream.
var updateRequest = ds.Files.Update(updateFileBody, fileId, uploadStream, MIME);
var result = await updateRequest.UploadAsync(CancellationToken.None);
uploadStream.Flush();
uploadStream.Close();
}
} catch (Exception EE)
{
string h = EE.Message;
}
}
As it seems to me, it may be happening that after the update call is made through the drive.service established with Google Drive with updateRequest the process stops on my site and loses the ability to pick up the thread. But I have no idea why. The update occurs but I need to receive the return on the client because after the thread is lost the application becomes inactive and does not respond to any events.
The outline of the process described is as follows:
I edit to add screenshots of the network tool related to the request Ajax
Edited to comment on the result of a test that limits the problem.
I've run the update method from the server, suppressing the initial Ajax send from the client. An error still occurs after successfully updating. The error message is: "System.NullReferenceException: 'Reference to object not set as an instance of an object.'"
I have the solution
The code example I referenced uses "await using". However, that feature does not exist in c# 5. I am using only "using". In that case the asynchronous method UploadAsync() causes the problem. It is not expected and a NullReferenceException is thrown. I use the synchronous Update() method instead. And now the return from Google Drive does occur and the ASP.NET application does not stop.
I've gathered all the code into a single method since I'm not using await to wait for the second method. The code looks like this:
public async Task<string> ActualizarArchivoDrive(string nombrefile, string extension, string nombrefilesinext, string extensionO, string idFile, string idFolder)
{
string extGuardar = (extension != extensionO ? "jpg" : extensionO);
Google.Apis.Drive.v3.DriveService ds = CodigoGeneral.Globales.gds;
string filePath = (string)HttpContext.Current.Server.MapPath("~") + "google/archivoseditados/" + nombrefilesinext + "." + extGuardar;
var updateFileBody = new Google.Apis.Drive.v3.Data.File()
{
Name = nombrefile,
};
FileStream uploadStream =
new FileStream(filePath, FileMode.Open, FileAccess.Read);
using (uploadStream)
{
//// Update the file id, with new metadata and stream.
Google.Apis.Drive.v3.FilesResource.UpdateMediaUpload updateRequest =
new Google.Apis.Drive.v3.FilesResource.UpdateMediaUpload(ds, updateFileBody, idFile, uploadStream, "image/jpeg");
var result = updateRequest.Upload();
if (result.Status == UploadStatus.Completed)
{
return "Finalizado";
}
}
}