使用 fetch 时如何 return 来自 MVC 控制器的错误

How to return an error from a MVC Controller when using fetch

.Net 框架 4.6.1

我设置了以下代码来将文件上传到服务器。

如果文件名不在数据中,我想将特定的错误消息返回给 fetch,以便将其显示给用户。

return 错误消息的正确方法是什么?

fetch(url, {
    method: 'POST',
    body: data,
}).then(function (response) {
     if (!response.ok) {
         return response.json()
             .then(function (obj) {
                 throw Error(obj.ErrorMessage)
             })
     }
     else {
         return response.json()
             .then(json => {
                 /*further processing */
             })
     }
 }).catch(/* work with the error */)


/// Uploads the file chunk.
/// </summary>
/// <param name="collection">The collection.</param>
/// <returns>
/// ActionResult
/// </returns>
[HttpPost]
[ValidateAntiForgeryToken]
[Log(ClickTrackingItemTypeConstants.DataPost)]
public async Task<ActionResult> UploadFileChunk(FormCollection collection)
{
    var fileDataParam = JsonConvert.DeserializeObject<UploadFileChunkFileDataModel>(collection["fileDataParam"]);

    if (fileDataParam == null)
    {
        throw new RubixGenericException(nameof(fileDataParam));
    }

    fileDataParam.FileName = string.Empty;
    if (string.IsNullOrWhiteSpace(fileDataParam.FileName) == true)
    {
        throw new Exception("error...");
    }

    fileManagerUtilities.AppendContentToFile(fileDataParam.FileGuid, fileDataParam.FileExtension, Request.Files[0]);

    if (fileDataParam.ChunkIndex == (fileDataParam.ChunkTotalCount - 1))
    {
        System.Diagnostics.Debug.WriteLine("file can be uploaded now");
    }

    return Json(new { success = true });
}

响应如下所示:

正如 Jasen 所写,您总是可以 ````return BadRequest(jsonData)``` 并在 frontApp 上显示错误消息。或任何其他操作结果

这是我的最终代码:

感谢@Jasen 的帮助!

我现在只需设置 statusCode 然后返回一个 JSON 对象即可正常工作。

我想当它调用 response.Json()

时我没有正确解析它
function uploadFileChunkFileManager(fileData, chunksInfo, destinationDir) {
    var deferred = $.Deferred();

    const formData = new FormData();

    formData.append('file', chunksInfo.chunkBlob);

    let fileManagerJsParam = getFileManagerParams(destinationDir, true);

    if (chunksInfo.chunkIndex === 0) {
        chunksInfo.customData.fileGuid = uuidv4();
    }

    let fileDataParam = {
        BytesUploaded: chunksInfo.bytesUploaded,
        ChunkIndex: chunksInfo.chunkIndex,
        ChunkTotalCount: chunksInfo.chunkCount,
        FileIndex: chunksInfo.fileIndex,
        FileName: fileData.name,
        FileSize: fileData.size,
        FileType: fileData.type,
        FileGuid: chunksInfo.customData.fileGuid,
        FileManagerJsParam: fileManagerJsParam
    }

    formData.append('fileDataParam', JSON.stringify(fileDataParam));
    formData.append('__RequestVerificationToken', $('[name=__RequestVerificationToken]').val());

    let url = BuildSafeURL(baseEndPoint + "UploadFileChunk", null);

    fetch(url, {
        method: 'POST',
        body: formData,
    }).then(function (response) {
        if (!response.ok) {
            return response.json()
                .then(function (error) {
                    deferred.reject({
                        errorId: 27000,
                        errorText: error.errorMessage,
                        fileItem: destinationDir,
                    })
                }).catch(error => {
                    //error handling for json parsing errors (empty body etc.)
                    console.log("Successful request, Could not parse body as json", error);
                    deferred.reject(uploadFileGenericErrorMessage(destinationDir));
                })
        }
        else {
            deferred.resolve();
            console.log('done... with upload..')
        }
    }).catch(function (error) {
        console.log(error);
        deferred.reject(uploadFileGenericErrorMessage(destinationDir));
    })

    return deferred.promise()
}
        /// <summary>
        /// Uploads the file chunk.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <returns>
        /// ActionResult
        /// </returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        [Log(ClickTrackingItemTypeConstants.DataPost)]
        public async Task<ActionResult> UploadFileChunk(FormCollection collection)
        {
            var fileDataParam = JsonConvert.DeserializeObject<UploadFileChunkFileDataModel>(collection["fileDataParam"]);

            if (fileDataParam == null)
            {
                throw new GenericException(nameof(fileDataParam));
            }

            if (string.IsNullOrWhiteSpace(fileDataParam.FileName) == true)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { errorMessage = "File name is required." });
            }

            fileDataParam.FileExtension = Path.GetExtension(fileDataParam.FileName);

            if (string.IsNullOrWhiteSpace(fileDataParam.FileExtension) == true)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { errorMessage = "File extension is required." });
            }

            if (Request.Files.Count == 0)
            {
                throw new GenericException("Request.Files.Count is 0");
            }

            if (Request.Files.Count > 1)
            {
                throw new GenericException("Request.Files.Count is greater than 2");
            }

            fileManagerUtilities.AppendContentToFile(fileDataParam.FileGuid, fileDataParam.FileExtension, Request.Files[0]);

            if (fileDataParam.ChunkIndex == (fileDataParam.ChunkTotalCount - 1))
            {
                System.Diagnostics.Debug.WriteLine("file can be uploaded now");
            }

            // allow to build until I update the code to save to the db
            await fileManagerUtilities.DownloadFile("285", 107).ConfigureAwait(false);

            return Json(new { success = true });
        }