我从客户端向服务器发送 Ajax 请求并期待返回。
$.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.");
}
});
通话成功。在服务器上已有的例程中,将对 Google Drive 中的文件执行更新。此更新已成功执行,但响应未返回给客户端。该过程不会向客户端返回任何内容。
我已经通过将代码减少到最少来进行检查,然后每次都添加一个新行。除非到达线路,否则始终会向客户端返回:
var result = await updateRequest.UploadAsync(CancellationToken.None);
从接收 Ajax 请求的模块中,我执行更新 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;
}
Google Drive文件的更新是使用以下方法进行的:
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";
}
如您所见,前面的方法使用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;
}
}
在我看来,可能会发生这样的情况:通过使用 updateRequest 与 Google Drive 建立的drive.service 进行更新调用后,该进程会在我的网站上停止并失去获取线程的能力。但我不知道为什么。更新发生,但我需要在客户端接收返回,因为线程丢失后应用程序变得不活动并且不响应任何事件。
描述的过程概要如下:
编辑以评论限制问题的测试结果。
我已经从服务器运行了更新方法,抑制了来自客户端的初始 Ajax 发送。 更新成功后仍然出现错误。错误消息是:“System.NullReferenceException:'对对象的引用未设置为对象的实例。'”
我有解决办法
我引用的代码示例使用“await using”。但是,c# 5 中不存在该功能。我仅使用“using”。在这种情况下,异步方法 UploadAsync() 会导致问题。这不是预期的结果,并且会引发 NullReferenceException。我改用同步 Update() 方法。现在确实发生了从 Google Drive 返回,并且 ASP.NET 应用程序也没有停止。
我已将所有代码收集到一个方法中,因为我没有使用await 来等待第二个方法。代码如下所示:
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;
uploadedFile back.
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");
updateRequest.Upload();
}
return "Finalizado";
}