Home > Back-end >  Json Response empty values
Json Response empty values

Time:07-20

I've got an controller action (which I found the basis from on SO somewhere, can't find the original now) that provides a file upload and responds back with a JSON payload including the URL of the uploaded file, which I have built to work with CKEditor.

If I put a breakpoint in to see the response value success I can see the properly JSON object looks as I would expect.

However, the response in browser is returning an empty list.

Controller Action

[HttpPost]
public async Task<ActionResult> Upload(IFormFile upload, string CKEditorFuncNum, string CKEditor, string langCode)
{
    var user = await _userManager.GetUserAsync(User);
    var admin = _context.LeagueAdmins.Include(i => i.League).FirstOrDefault(i => i.User.Id == user.Id);
    if (user == null)
    {
        throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
    }

    if (upload.Length <= 0) return null;

    if (!upload.IsImage())
    {
        var NotImageMessage = "You must upload a picture";
        dynamic NotImage = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \""   NotImageMessage   "\"}}");
        return Json(NotImage);
    }

    var fileName = Guid.NewGuid()   Path.GetExtension(upload.FileName).ToLower();

    Image image = Image.FromStream(upload.OpenReadStream());
    int width = image.Width;
    int height = image.Height;
    if ((width > 2000) || (height > 2000))
    {
       var DimensionErrorMessage = "Your image is too big. It must be a maximum of 2000px height and width";
       dynamic stuff = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \""   DimensionErrorMessage   "\"}}");
       return Json(stuff);
    }

    if (upload.Length > 500 * 1024)
    {
       var LengthErrorMessage = "The file is too big. Maximum file size is 5mb";
       dynamic stuff = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \""   LengthErrorMessage   "\"}}");
       return Json(stuff);
    }
    var directory = Path.Combine(_env.WebRootPath, "uploads", admin.League.Id.ToString(), "pages");
    var path = Path.Combine(directory, fileName);

    if (!Directory.Exists(directory))
    {
         var mkdir = Directory.CreateDirectory(directory);
    }

    try
    {
        using (var stream = new FileStream(path, FileMode.Create))
        {
             await upload.CopyToAsync(stream);
        }
    }
    catch (Exception ex)
    {
        var exception = ex.Message;
    }
           
    var url = $"{"/uploads/"   admin.League.Id.ToString()   "/pages/"}{fileName}";
    var successMessage = "File is uploaded successfully";
    var success = JsonConvert.DeserializeObject("{ 'uploaded': 1,'fileName': \""   fileName   "\",'url': \""   url   "\", 'error': { 'message': \""   successMessage   "\"}}");
    return Json(success);
}

Value of object in breakpoint

enter image description here

Response in Browser

enter image description here

CodePudding user response:

This is very unconventional approach from standard C# practices point of view:

var success = JsonConvert.DeserializeObject("{ 'uploaded': 1,'fileName': \""   fileName   "\",'url': \""   url   "\", 'error': { 'message': \""   successMessage   "\"}}");

Just create a class and instantiate, fill the data and return it. If you don't want to create a special class use an anonymous type feature:

var success = new
{
    uploaded = 1,
    fileName = fileName,
    url = url,
    error = new
    {
        message = successMessage
    }
};

return Json(success); // or Ok(success)

P.S.

Also string interpolation here looks quite strange too:

var url = $"{"/uploads/"   admin.League.Id.ToString()   "/pages/"}{fileName}";

Should not it be just:

var url = $"/uploads/{admin.League.Id}/pages/{fileName}";

?

  • Related