Click here to Skip to main content
15,867,973 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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:
C#
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:
C#
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:
C#
async Task UploadImage()
        {
          await CrossMedia.Current.Initialize();
        // await CrossPermissions.Current.RequestPermissionAsync<CameraPermission>();
            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:
C#
[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:
C#
 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.
Posted
Updated 30-Jul-20 4:30am
v2

1 solution

Object reference not set to an instance of an object
 
This error happens when you try to use a property or call a method of an object that is null. More details: here[^]
 
A simple use of Visual studio DEBUGGER can tell you the object because of which it is happening. Just look at the stack trace and put a debugger on that line. Check the objects of that line and see if any one is null and you are trying to use that objects property. Handle the same.
 
Share this answer
 
Comments
Eliza Maria 30-Jul-20 10:11am    
Thank you for your response Sandeep. It seems like it gets the image so it is not a null value but it returns an error "500 Bad request"
Sandeep Mewara 30-Jul-20 10:22am    
So you know where things are going wrong. Now two things:
1. Handle such case that does not lead to ORE. Your code should handle such bad response.
2. Find why you are getting 500 error and get that resolved.
Eliza Maria 30-Jul-20 10:35am    
ok,so after I researched a little bit I have managed to find something that returns a 200 ok status code.However I have 2 things i can't put my finger on:
1.Although it returns "OK",the file is not saved in the folder on the server side.
2.As I have changed the method to take another parameter named "fileName" I'm not sure how to use it in the VM so that will actually get the image name.

I have updated the question with the new code I have right now for UploadPictureAsync() and UploadImage().Thank you again for your help in figuring out how to resolve this :)
Sandeep Mewara 30-Jul-20 10:45am    
As you are trying new things now, would suggest instead of updating the same question, start a new one with your new issues for clarity.
Eliza Maria 30-Jul-20 10:47am    
ok Sandeep,thanks for your help.I'll do that now.Best regards!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900