Hi!
I am trying to upload a picture to .net server with xamarin but I have a problem apparently on the client side.When I am trying to post an image with Postman directly on the server side,everything works perfectly and the image ins saved into a folder in wwwroot.However,when I select the picture on the client side,I get this error "
System.NullReferenceException: Object reference not set to an instance of an object.
I am using "Xam.Plugin.Media" nuget which takes the image as Media file and I convert it to bytes so that it is stored in the database as in the model it is declared as byte array.I tried to make the api method in the webservice to take the image as mediafile,but for some reason it throws the error I mentioned above.My guess is that because the server side has the image as IFormFile and I try to send it as MediaFile,it will declare it as a null object.
This is my model class:
public class User
{
public int IdUser { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string ConfPassword { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
public DateTime? Dob { get; set; }
public byte[] Picture { get; set; }
public virtual ICollection<Login> Login { get; set; }
}
The client-side api method:
public void UploadPicture(MediaFile image,string fileName)
{
<pre> HttpContent fileStreamContent = new StreamContent(image.GetStream());
fileStreamContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") { Name = "file", FileName = fileName };
fileStreamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
using (var client = new HttpClient(clientHandler))
using (var formData = new MultipartFormDataContent())
{
formData.Add(fileStreamContent);
var response = await client.PostAsync(pictureUrl, formData);
if(response.IsSuccessStatusCode)
{
}
}
}
The ViewModel command method to get the image and convert it to byte array:
async Task UploadImage()
{
await CrossMedia.Current.Initialize();
var mediaOptions = new PickMediaOptions()
{
PhotoSize = PhotoSize.Medium
};
var selectedImageFile = await CrossMedia.Current.PickPhotoAsync(mediaOptions);
using (var memoryStream = new MemoryStream())
{
selectedImageFile.GetStream().CopyTo(memoryStream);
Picture = memoryStream.ToArray();
await service.UploadPictureAsync(selectedImageFile,selectedImageFile.ToString());
}
if (selectedImageFile == null)
{
await Application.Current.MainPage.DisplayAlert("Error", "Could not get file", "ok");
return;
}
}
The server-side method which works:
[HttpPost]
public async Task Post(IFormFile file)
{
if (string.IsNullOrWhiteSpace(_environment.WebRootPath))
{
_environment.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
}
var uploads = Path.Combine(_environment.WebRootPath, "uploads");
if (!Directory.Exists(uploads)) Directory.CreateDirectory(uploads);
if (file.Length > 0)
{
using (var fileStream = new FileStream(Path.Combine(uploads, file.FileName), FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
}
}
Is there any workaround that will allow me to convert the Mediafile into IFormFile to send it to the server or how should i approach this?Any help would be appreciated!
What I have tried:
I tried to adjust the api method to receive the media file like so:
public void UploadPicture(MediaFile image)
{
string pictureUrl = "http://10.0.2.2:5000/api/UploadPicture";
<pre> try
{
StreamContent content = new StreamContent(image.GetStream());
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = "newimage",
Name = "image"
};
content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
var client = new HttpClient(clientHandler);
var multi = new MultipartFormDataContent();
multi.Add(content);
var result = client.PostAsync(pictureUrl, multi).Result;
}
catch (Exception e)
{
}
As it is my first time when I am working with file upload I took the method from xamarin forum,it's not written by me.