4

I have Web API controller in mt server side

[HttpPost("CreateImage")]
    public void CreateImage([FromBody] ImageDTO img)
    {
        Image image = new Image { FileName = img.FileName };
        byte[] imageData = null;
        using (var binaryReader = new BinaryReader(img.Image.OpenReadStream()))
        {
            imageData = binaryReader.ReadBytes((int)img.Image.Length);
        }
        image.Picture = imageData;

        imageRepo.Create(image);

    }

Where ImageDTO is

     public class ImageDTO
    {
        public string FileName { get; set; }

        public IFormFile Image { get; set; }
    }

and Image.cs like this

public class Image
   {
      public int Id { get; set; }

      public string FileName{ get; set; }

      public byte[] Picture { get; set; }

      public List<User> Users { get; set; }
   }

And this is what I using for handling and sending image on React client:

<form>
        <p>
            <label>Аватар</label>
            <input name="Avatar" id = 'img' type="file" class="form-control" onChange={(e)=>this.handleImageChange(e)}/>
        </p>
        <p>
            <input type="submit" value="Добавить" onClick={this.sendImage}/>
        </p>
</form>
      <div className="imgPreview">
      {$imagePreview}
    </div>

function for handling file into state

    handleImageChange(e) {
    e.preventDefault();
    let form = new FormData();
    for (var index = 0; index < e.target.files; index++) {
      var element = e.target.files[index];
      form.append('file', element);
  }
    this.setState({file: form});
  }

sending it on server

async sendImage(event) {
event.preventDefault();

console.log(this.state.file);
await addImage(this.state.file);
console.log('it works');}

addImge function:

addImage = async ( image)  => {

    await fetch('https://localhost:44331/api/users/CreateImage',
        {
            method: 'POST',
            mode: 'cors',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + sessionStorage.tokenKey
            },
             body:  JSON.stringify({
                FileName: 'Img',
                Image: image
            })
        }
    )
}

But when it`s sending request on server it return Error 400, which means "Bad Request". So I think it is may be wrong type of data sent or something like that. Maybe someone sees a mistake or something that can be fixed. Or someone could show a working example of sending images from React to Web Api server. I need your help guys!

7
  • 1
    You can't stringify binary data. You should send FormData in request's body Commented Mar 17, 2019 at 8:26
  • I changed my controller so it take ([FromForm]IFormFile body) but now it gets an empty data. Commented Mar 17, 2019 at 8:33
  • Also i send FormData from client too. Commented Mar 17, 2019 at 8:34
  • For real it gets error 500 but I thing it is because of null data. Commented Mar 17, 2019 at 8:37
  • In Developers tools of your browser see what request has been sent to server. Commented Mar 17, 2019 at 8:55

1 Answer 1

6

For uploading, you need to pay attention to points below:

  1. You need to use formdata with FromForm
  2. The fields in formdata should be corresponding to the model fields.

Steps:

  1. Change the Controller action.

    public void CreateImage([FromForm] ImageDTO img)
    {
    
    }
    
  2. Client Code:

    async sendImage(event) {
        event.preventDefault();
        console.log(this.state.file);
        await this.addImage(this.state.file);
        console.log('it works');
    };
    addImage = async (image) => {
        await fetch('https://localhost:44385/api/users/CreateImage',
            {
                method: 'POST',
                mode: 'cors',
                headers: {
                    'Accept': 'application/json',
                    'Authorization': 'Bearer ' + sessionStorage.tokenKey
                },
                body: this.state.file
            }
        )
    }
    
    handleImageChange(e) {
        e.preventDefault();
        let form = new FormData();
        for (var index = 0; index < e.target.files.length; index++) {
            var element = e.target.files[index];
            form.append('image', element);
        }
        form.append('fileName', "Img");
        this.setState({ file: form });
    };    
    
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much, it works perfectly! This decision did not even occur to me, although I thought that I had tried everything.You delivered me from suffering :)
How i can implement this in .net WebAPI 2.0 ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.