Search code examples
c#asp.net-web-apibase64swift2alamofire

Invalid length for a Base-64 char array or string c# mvc4 web Api


I am using swift 2.0 and Alamofire 3.0. I made a POST request with Alamofire. Parameters in my request contained text and a base64 encoded image. But I am getting a Message as response saying "An error occurred". Asp.net mmvc4 web api is used as backend. The base64 string seems too long. by using an online text editor editpad. in that I found that the character count of my base64 string is 4405562 Characters (including whitespace)

Image to base64 code (swift 2)

 var userProfileImage : String = ""
       func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

        let capturedImage : UIImage
            if let _image = info["UIImagePickerControllerEditedImage"] as? UIImage

                {
                    capturedImage = _image
                    self.profilePicture.image = _image

                    let imagetosave = UIImageJPEGRepresentation(_image, 1.0)
                    let base64encodedImage  = imagetosave!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength) 
                    userProfileImage =  base64encodedImage



                        }
            }
                    else if let _image = info["UIImagePickerControllerOriginalImage"] as? UIImage
                        {
                            capturedImage = _image
                            var __image = UIImageJPEGRepresentation(_image,1.0)

                            let base64encodedImage = __image!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)

                            userProfileImage =  base64encodedImage

                            self.profilePicture.image = _image

                        }
                            else
                                {
                                    return
                                }

        dismissViewControllerAnimated(true, completion: nil)

}

Alamofire POST Request

let params = ["userid":"\(user)" , "firstname":"\(String(_firstName))" , "middlename":"\(String(_middlename))","lastname":"\(String(_lastname))","password":"\(String(_pass))","email":"\(String(_email))","oldpassword":"\(_oldpass)","base64String":"userProfileImage"]


        Alamofire.request(.POST, App.AppHomeURL() + "Update_Profile", parameters : params , encoding : .JSON).responseJSON{
            response in
      switch response.result {
      case .Success(let data) :
      let json = JSON(data)
      let _data : String = json["Data"].string!
      if (_data == "true")
          {
          let _storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let _profile = _storyBoard.instantiateViewControllerWithIdentifier("ProfileViewController") as! ProfileViewController
                       self.navigationController?.pushViewController(_profile, animated: true)
                        }

Here I get the JSON response as "Message" : "An error has occurred"

Backend code that receives the POST request

public JsonResult Update_Profile([FromBody]UpdateProfileViewModel updateprofileviewmodel)
{
  //code goes here

 if (updateprofileviewmodel.base64String != "" && updateprofileviewmodel.base64String != null && updateprofileviewmodel.base64String != "null")
            {
                byte[] imageBytes = Convert.FromBase64String(updateprofileviewmodel.base64String); 
                MemoryStream ms = new MemoryStream(imageBytes, 0,
                  imageBytes.Length);
                // Convert byte[] to Image
                ms.Write(imageBytes, 0, imageBytes.Length);
                Image image = Image.FromStream(ms, true);
                string filenametosave = usermodel._id + "." + System.Drawing.Imaging.ImageFormat.Jpeg;
                var path = System.Web.Hosting.HostingEnvironment.MapPath("~/Content/FridgeUserProfilePictures/" + filenametosave);
                if (System.IO.File.Exists(path))
                {
                    System.IO.File.Delete(path);
                }
                image.Save(path);
                usermodel.Photo = filenametosave;
            }
} 

here in the line byte[] imageBytes = Convert.FromBase64String(updateprofileviewmodel.base64String);

an exception occurs saying

An exception of type 'System.FormatException' occurred in mscorlib.dll but was not handled in user code Additional information: Invalid length for a Base-64 char array or string.

EDIT : Just put the Base64 string got from Swift in a variable in webApi method

var base64String = "Base64 string got in ios" this worked and created an image in server. I tried using POSTMAN a google extension. on using it I found that the actual String is not getting passed. say the string length is 100 on passing only string with length 50 is send and produced the error mentioned in the Question. later I tried this and the response is

response = Optional(<NSHTTPURLResponse: 0x7fe593618b30> { URL: http://app.appurl } { status code: 500, headers {
    "Cache-Control" = private;
    "Content-Length" = 3420;
    "Content-Type" = "text/html; charset=utf-8";
    Date = "Tue, 01 Dec 2015 11:59:22 GMT";
    Server = "Microsoft-IIS/8.0";
    "X-AspNet-Version" = "4.0.30319";
    "X-Powered-By" = "ASP.NET";
} })

<html>

<head>
  <title>Runtime Error</title>
  <meta name="viewport" content="width=device-width" />
  <style>
    body {
      font-family: "Verdana";
      font-weight: normal;
      font-size: .7em;
      color: black;
    }
    p {
      font-family: "Verdana";
      font-weight: normal;
      color: black;
      margin-top: -5px
    }
    b {
      font-family: "Verdana";
      font-weight: bold;
      color: black;
      margin-top: -5px
    }
    H1 {
      font-family: "Verdana";
      font-weight: normal;
      font-size: 18pt;
      color: red
    }
    H2 {
      font-family: "Verdana";
      font-weight: normal;
      font-size: 14pt;
      color: maroon
    }
    pre {
      font-family: "Consolas", "Lucida Console", Monospace;
      font-size: 11pt;
      margin: 0;
      padding: 0.5em;
      line-height: 14pt
    }
    .marker {
      font-weight: bold;
      color: black;
      text-decoration: none;
    }
    .version {
      color: gray;
    }
    .error {
      margin-bottom: 10px;
    }
    .expandable {
      text-decoration: underline;
      font-weight: bold;
      color: navy;
      cursor: hand;
    }
    @media screen and (max-width: 639px) {
      pre {
        width: 440px;
        overflow: auto;
        white-space: pre-wrap;
        word-wrap: break-word;
      }
    }
    @media screen and (max-width: 479px) {
      pre {
        width: 280px;
      }
    }
  </style>
</head>

<body bgcolor="white">

  <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>

            <h2> <i>Runtime Error</i> </h2></span>

  <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

            <b> Description: </b>An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.
            <br><br>

            <b>Details:</b> To enable the details of this specific error message to be viewable on remote machines, please create a &lt;customErrors&gt; tag within a &quot;web.config&quot; configuration file located in the root directory of the current web application. This &lt;customErrors&gt; tag should then have its &quot;mode&quot; attribute set to &quot;Off&quot;.<br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>

&lt;!-- Web.Config Configuration File --&gt;

&lt;configuration&gt;
    &lt;system.web&gt;
        &lt;customErrors mode=&quot;Off&quot;/&gt;
    &lt;/system.web&gt;
&lt;/configuration&gt;</pre></code>

                  </td>
               </tr>
            </table>

            <br>

            <b>Notes:</b> The current error page you are seeing can be replaced by a custom error page by modifying the &quot;defaultRedirect&quot; attribute of the application&#39;s &lt;customErrors&gt; configuration tag to point to a custom error page URL.<br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>

&lt;!-- Web.Config Configuration File --&gt;

&lt;configuration&gt;
    &lt;system.web&gt;
        &lt;customErrors mode=&quot;RemoteOnly&quot; defaultRedirect=&quot;mycustompage.htm&quot;/&gt;
    &lt;/system.web&gt;
&lt;/configuration&gt;</pre></code>

                  </td>
               </tr>
            </table>

            <br>

    </body>
</html>
)


Solution

  • May not be the answer for you but I did this, Compress the Image before sending it to the server and now everything works fine.