locked
Passing base64 string to web api RRS feed

  • Question

  • User-920806005 posted

    Hi guys!

    I'm trying to upload image from client to server.

    The image in base64 string works in client side, because it is displayed correctly into an image viewer.

    Then, when I try to upload the image the file created is corrupted, and I can't open it. It seems that I'm loosing some part of base64 string passing it from client side to server side.

    Server side code:

    [Produces("application/json")]
        [Route("api/pubblicazioni")]
        public class PubblicazioniController : Controller
        {
            [Route("crea")]
            [HttpPost]
            public IActionResult CreaPubblicazione(Int32 idutente, String testo, String immagine)
            {
                if (Pubblicazione.CreaPubblicazione(idutente, testo, immagine) == true)
                {
                    return Ok();
                }
                else
                {
                    return Unauthorized();
                }
            }
    }
    
    
            public static bool CreaPubblicazione(Int32 idutente, String testo, String immagine)
            {
                        var bytes = Convert.FromBase64String(immagine);
    
                        String nomefile = idpubblicazione.ToString() + ".jpg";
                        File.WriteAllBytes(path + nomefile, bytes);
    
                        return true;
                    }
                    catch (Exception ex)
                    {
                        return false;
                    }
                }
            }
    

    Here it is my client side code:

    Pubblica(idutente: any, testo: any, immagine: any) {
                var headers = new Headers();
            headers.append('Content-Type', 'application/x-www-form-urlencoded');
            let options = new RequestOptions({ headers: headers });
            let params = new URLSearchParams()
            params.set('idutente', idutente);
            params.set('testo', testo);
            params.set('immagine', immagine);
        
            return new Promise((resolve, reject) => {
            this.http.post(this.conn.connessione+"/api/pubblicazioni/crea", params.toString(), options)
              .subscribe(
                data => {
                  resolve(data);
                },
                error => {
                  reject(error);
                }
              );
            });
    const options: CameraOptions = {
          quality: 100,
          destinationType: this.camera.DestinationType.FILE_URI,
          encodingType: this.camera.EncodingType.JPEG,
          mediaType: this.camera.MediaType.PICTURE,
          sourceType:sourceType
        }

    }
    Thursday, April 26, 2018 8:53 PM

All replies

  • User36583972 posted


    Hi Pasto92,

    Do you receive any error code in F12 debug tool?

    Data can be either transmitted in the URL of a request, or in the body. And the URL is only allowed to be a finite length.

    I suggest you can use [FromBody] attribute to put your base64 string in the body and Web API can read this from the request body.

    The following links give solutions under different circumstances. You can refer it.

    ASP.NET Web API does not allow Lengthy base64 URI:

    Base64 string in WebClient.UploadValues to Web API gets cut off

    posting base64 data and saving image into folder

    Best Regards,

    Yong Lu

    Friday, April 27, 2018 8:33 AM
  • User-920806005 posted

    Thank you for the reply!

    I found the problem.

    Base64 string contains a lot of '+' carachters. This carachter is automatically converted to '%20' when I pass the string to server side code. It seems that my web api doesn't recognize '+' carachter, so it becomes '%20'. How can I solve this? (I can replace '%20' to '+' in my server side code, but I'd like to know if there is a more elegant method)

    Friday, April 27, 2018 8:58 AM
  • User753101303 posted

    Hi,

    + is a way to encode spaces inside a url.

    Not sure exactly what is going on but when I have this kind of issue and can't spot what happens, my approach is to use HttpRequest.SaveAs for both a form and my API. This way I can spot easily spot differences between the two requests and fix the missing header or whatever...

    Edit: not directly related but using multipart/form-data could be better ?

    Edit: as pointed by others I found suprising that URLSearchParams doesn't do that already for you. Actually I didn't know about this. Is this https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams which doesn't seems to be available for IE. If using IE could it be a polyfill bug ?

    Friday, April 27, 2018 11:03 AM
  • User-474980206 posted

    in the early days of the web the "+" was used to replace a space instead of using %20. so when url unescape is done, a "+" is converted to a space. if you want to pass a "+" as a url encoded value, you need to use %2B. the javascript method encodeURIComponent() does this properly. it looks like your data encoder (URLSearchParams) has a bug.  

    note: generally if the url builder does not handle "+" it also does not handle "=" (the base64 filler char)

     

    Friday, April 27, 2018 3:33 PM
  • User-369506445 posted

    Hi

    This a common anomaly that we face while adding parameters in the url's. Here you can have a hint of what your OP is and what you might need at a later run

    You can have many options as for + you can encode in your java script file using

    encodeURIComponent();

    And also for your ease if you want to add any special characters in your url like a .then simply set the property relaxedUrlToFileSystemMapping in your web.config

    <system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true" />

    Or you can just add or remove some of the characters to block/allow using requestPathInvalidCharacters in your web.config

    <httpRuntime requestPathInvalidCharacters="&lt;,&gt;,*,%,&amp;,:,\,?"/>
    Friday, April 27, 2018 3:44 PM