2

I would like to add an attachment, I use .net core 2.0 and react(redux). On backend i have ORM db EF. This is Model:

    public byte[] Attachment { get; set; }

My attachment is in byte[] on backend. This is my React code: Function:

   fileSelectedHandler = event => {
    this.setState({
        attachment: event.target.files[0]
    })
}

Constructor:

 this.state = {
   attachment: null
 }

onSubmit:

    const fd = new FormData();
     const test = fd.append('attachment', this.state.attachment, 
     this.state.attachment.name);

     const reportData = {
            attachment: test
        };
    this.props.addReport(reportData, url);

Unfortunately, it does not work, I have no idea to solve this problem.

SOLUTION:

    fileSelectedHandler = event => {
        let reader = new FileReader();
        reader.readAsDataURL(event.target.files[0]);
        if(event.target.files[0].size < 2097152){ // max 2mb files
            reader.onloadend = () => {
                this.setState({
                    attachment : reader.result.split(';base64,')[1]
                }) 
            };
        }
        else{
            tost.error('Plik powinien być mniejszy niż 2mb.'); // tost.error for file should be smaller than 2mb
            reader.onloadend = () => {
                this.setState({
                    attachment : null
                }) 
            };
        }

ReportAction:

  // Add Report
     export const addReport = (postData, prevUrl) => dispatch => {
      const config = {
    headers: {
      'enctype' : 'multipart/form-data' // it's important!
    }
  }
    axios
      .post(`${API_ROUTE}/api/Reports`, postData, config)
      .then( () => {
        const toastrOptions = {
          timeOut: 2000
        }
        if(prevUrl === "/reports"){
          dispatch(getReports())
        }
        tost.success('Pomyślnie dodano raport', toastrOptions);
      })
      .catch(err => {
        tost.error(err.response.data.errorMessage);
        dispatch({
          type: GET_ERRORS,
          payload: err.response.data
        })}
      );
};

Backend Controller:

    [AllowAnonymous]
    [HttpPost]
    public async Task<IActionResult> Add([FromBody] ReportDto reportDto)
    {
        var report = _mapper.Map<ReportDto, Report>(reportDto);

        var addedReport = await _service.AddReport(report);

        var uri = Request.PathBase.Value.ToString();

        return Created(uri, addedReport);
    }

ReportDto is the includ same props above.

1
  • what is the type of attachment here in react? Commented Sep 18, 2020 at 4:03

1 Answer 1

1

First you have to change your chosen file attachment to form Data

function toFormData(file: File) {
    const data = new FormData();
    data.append("file", file);
    return data;
}

Then you have to submit your form data using sth like this:

async function uploadFile(url: string, file: File, onProgress?: (progress: number) => void) {
    const data = toFormData(file);
    const xhr = new XMLHttpRequest();
    return new Promise((resolve, reject) => {
        if (typeof onProgress === "function") {
            xhr.upload.onprogress = event => {
                onProgress(event.loaded / event.total);
            };
        }

        xhr.onload = () => {
            let response;
            try {
                response = JSON.parse(xhr.response);
            } catch (err) {
                response = xhr.response;
            }

            if (xhr.status >= 200 && xhr.status < 300) {
                resolve(response);
                return;
            }
            reject(response);
        };

        xhr.onerror = err => {
            reject(err);
        };

        xhr.open("POST", url);
        xhr.send(data);
    });
}

And finally you can consume your submitted attachment in Action using IFormFile intraface:

[HttpPost]
[Route("Attachment")]
public async Task Attachment([FromForm] IFormFile file)
{
    // do sth with attachment
}

Sign up to request clarification or add additional context in comments.

1 Comment

I found better way for my question. Solution in my post. Thanks :)

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.