Cómo enviar una image como Base64String utilizando la request POST Alamofire y cómo manejar la request en Asp.net MVC4 web Api Controller?

Un novato en iOS y para mi proyecto estoy usando Alamofire (3.0.0) y como Backend asp.net MVC4 web Api. He convertido mi image a base64string de esta manera

swift 2.0

var userProfileImage : String = "" func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { if let _image = info["UIImagePickerControllerEditedImage"] as? UIImage //if let _image = info["UIImagePickerControllerOriginalImage"] as? UIImage { captunetworkingImage = _image self.profilePicture.image = _image //cache.saveImage(captunetworkingImage, path: _cache.fileInDocumentsDirectory("profileImage")) let imagetosave = UIImageJPEGRepresentation(_image, 1.0) let base64encodedImage = imagetosave!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) userProfileImage = base64encodedImage } else if let _image = info["UIImagePickerControllerOriginalImage"] as? UIImage { let __image = UIImageJPEGRepresentation(_image,1.0) let base64encodedImage = __image!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) userProfileImage = base64encodedImage } } 

y mi request Alamofire es la siguiente

 let params = ["userid":"\(user)" , "firstname":"\(String(_firstName))" , "middlename":"\(String(_middlename))","lastname":"\(String(_lastname))","email":"\(String(_email))","base64String":"\(userProfileImage)"] Alamofire.request(.POST, App.AppHomeURL() + "Update_Profile", parameters : params, encoding : .JSON).responseJSON{ response in case .Success(let data) : let json = JSON(data) print("JSON DATA : \(json)") case .Failure(let error): print(error) } 

Y, finalmente, mi ApiController que acepta la request es

 [System.Web.Http.HttpPost] public JsonResult Update_Profile(string userid, string firstname, string middlename, string lastname, string email, string base64String) { // code goes here ... } 

¿Es la forma correcta de enviar una image a una API web usando Alamofire? ¿Obtuve el estado de respuesta como 404? ¿Cómo enviar imágenes usando Alamofire y velozmente a asp.net mvc4 web api y cómo manejar la request en Api Controller?

Actualmente lo que estoy haciendo es esto …

Obtenga la image de ImagePicker y conviértalo a la cadena Base64 y asígnela a una variable para usarla más tarde …

Nota: estoy comprimiendo mi image para que sea más pequeña y para poner ese código también

 var userProfileImage : String = "" func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { let captunetworkingImage : UIImage if let _image = info["UIImagePickerControllerEditedImage"] as? UIImage { captunetworkingImage = _image self.profilePicture.image = _image let _image_compressed = compressImage(_image) let imagetosave = UIImageJPEGRepresentation(_image_compressed , 1.0) let base64encodedImage = imagetosave!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength) userProfileImage = base64encodedImage } else if let _image = info["UIImagePickerControllerOriginalImage"] as? UIImage { captunetworkingImage = _image let _imageCompressed = compressImage(_image) let __image = UIImageJPEGRepresentation(_imageCompressed , 1.0) let base64encodedImage = __image!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue : 0)) userProfileImage = base64encodedImage self.profilePicture.image = _image } else { return } dismissViewControllerAnimated(true, completion: nil) } 

// Comprima la image

 func compressImage(image : UIImage) -> UIImage { var _actualImageHeight : CGFloat = image.size.height var _actualImageWidth : CGFloat = image.size.width let _maxHeight : CGFloat = 300.0 let _maxWidth : CGFloat = 400.0 var _imageRatio : CGFloat = _actualImageWidth / _actualImageHeight let _maxRatio: CGFloat = _maxWidth / _maxHeight let _imageCompressionQuality : CGFloat = 0.5 // makes the image get compressed to 50% of its actual size if _actualImageHeight > _maxHeight || _actualImageWidth > _maxWidth { if _imageRatio < _maxRatio { // Adjust thw width according to the _maxHeight _imageRatio = _maxHeight / _actualImageHeight _actualImageWidth = _imageRatio * _actualImageWidth _actualImageHeight = _maxHeight } else { if _imageRatio > _maxRatio { // Adjust height according to _maxWidth _imageRatio = _maxWidth / _actualImageWidth _actualImageHeight = _imageRatio * _actualImageHeight _actualImageWidth = _maxWidth } else { _actualImageHeight = _maxHeight _actualImageWidth = _maxWidth } } } let _compressedImage : CGRect = CGRectMake(0.0 , 0.0 , _actualImageWidth , _actualImageHeight) UIGraphicsBeginImageContext(_compressedImage.size) image.drawInRect(_compressedImage) let img: UIImage = UIGraphicsGetImageFromCurrentImageContext() let imageData: NSData = UIImageJPEGRepresentation(img, _imageCompressionQuality)! UIGraphicsEndImageContext() return UIImage(data: imageData)! } 

Este es mi método (IBAction) donde envío detalles del perfil de usuario al server que incluye la image Base64 como String

 @IBAction func saveUserDetails(sender: AnyObject) { let _oldpass = userOldPassword.text! let _newPass = userNewPassword.text! let _newPassCoonfirm = userRetypedPassword.text! let _email : String = userEmail.text! var _firstName : String = "" let _middlename : String = userMiddleName.text! let _lastname : String = userLastName.text! let _pass : String = userNewPassword.text! var _profileImage : String = "" if let profileImage = self.userProfileImage as? String { _profileImage = profileImage } else { _profileImage = "" } if let _first = userFirstName.text! as? String { _firstName = _first } else { _firstName = "" } let params = ["firstname":"\(String(_firstName))" ,"middlename":"\(String(_middlename))" ,"lastname":"\(String(_lastname))" ,"password":"\(String(_pass))" ,"email":"\(String(_email))" ,"oldpassword":"\(_oldpass)" ,"base64String":"\(_profileImage)"] 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 ProfileEdit = json["Data"] if (ProfileEdit) { print("true") } case .Failure(let _error): print("false") } } } 

Y esta es mi acción del controller Asp.Net MVC

 [route.System.Web.Http.HttpPost] [HttpRoute("api/Home/Update_Profile")] public JsonResult Update_Profile([FromBody]UpdateProfileViewModel updateprofileviewmodel) { UserModel usermodelforemail = Helper.FindUserByEmail(updateprofileviewmodel.email); System.Web.Mvc.JsonResult usertoreturn = new System.Web.Mvc.JsonResult(); UserModel usermodel = new UserModel(); usermodel = FridgeHelper.FindUserByObjectId(updateprofileviewmodel.userid); usermodel.FirstName = updateprofileviewmodel.firstname; usermodel.MiddleName = updateprofileviewmodel.middlename; usermodel.LastName = updateprofileviewmodel.lastname; usermodel.Email = updateprofileviewmodel.email; //save photo if (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/UserProfilePictures/" + filenametosave); if (System.IO.File.Exists(path)) { System.IO.File.Delete(path); } image.Save(path); usermodel.Photo = filenametosave; } bool resultvalue = false; resultvalue = Helper.UpdateUser(usermodel); if (resultvalue) { usertoreturn.Data = "true"; } else { usertoreturn.Data = "false"; } return usertoreturn; } 

Ahora todo funciona de la forma que necesitaba … 🙂