Skip to content

File uploading with PUT method with Method Override #4

Description

@weierophinney

I am trying to upload a file in a form with other data fields provided via Angular 4. With lot of difficulty I managed to get it posting properly. It requires that I remove the Content-Type header from the ajax posting.

So now both POST and PUT works as normally. However I have encountered a problem with apigility behavior when it comes to X-HTTP-Method-Override header. The POST method still works fine but PUT fails on input validation. Apigility reports all my required fields as empty when actually they are not.

As I said this happens only when I use POST with Method Overriding to PUT.

Also noticed that allow_empty and continue_if_empty does not work.

My production server does not support PUT & DELETE methods. So I need to get this working.

My module.config.php has the following for the specific file upload field:

6 => [
    'name' => 'projProposal',
    'required' => false,
    'filters' => [
        0 => [
            'name' => \Zend\Filter\File\RenameUpload::class,
            'options' => [
                'target' => 'data/uploads/projects/',
                'use_upload_extension' => true,
                'randomize' => true,
            ],
        ],
    ],
    'validators' => [
        0 => [
            'name' => \Zend\Validator\File\MimeType::class,
            'options' => [
                'mimeType' => 'pdf,doc,docx,xls,xlsx,application/vnd.openxmlformats-officedocument.wordprocessingml.document,enxmlformats-officedocument.spreadsheetml.sheet',
            ],
        ],
        1 => [
            'name' => \Zend\Validator\File\Size::class,
            'options' => [
                'max' => '10485760',
            ],
        ],
    ],
    'type' => \Zend\InputFilter\FileInput::class,
    'allow_empty' => false,
    'continue_if_empty' => true,
    'error_message' => 'Upload Failed.....',
],

My Template has the following among others:

<form (ngSubmit)="onSubmit(dataRecord)" #entryForm="ngForm">
  <div class="form-group " *ngIf="(action !== 'View') || (action !== 'Delete')">
    <label for="projProposal">Upload project proposal</label> 
    <input type="file"
      class="form-control" id="projProposal"
      title="Upload files of type .pdf,.doc,.docx" 
accept=".pdf,.doc,.docx"
      name="projProposal"
      minlength="1"
      maxlength="500"
      size="5em"
      [readonly]="(action === 'View') || (action === 'Delete')">
    <div *ngIf="formErrors.projProposal" class="alert alert-danger">{{
      formErrors.projProposal }}</div>
  </div>
</form>

My data service has the following:

editRecord (data: any): Observable<Response> {
  let url = this._url + '/' + data.get('projectId');
  const headers = new Headers({ 'Accept': '*/*',
    'X-HTTP-Method-Override': 'PUT', // Not required if the server support PUT method
    'Authorization': (this.authService.authresponse.token_type + ' ' + this.authService.getToken())
  });
  const options = new RequestOptions({ headers: headers});
  return this.http.post(url, data, options)
                  .map(this.extractData)
                  .catch(this.handleError);
}

The Response I get is:

{
  "validation_messages": {
    "projDesc": {
      "isEmpty": "Value is required and can't be empty"
    },
    "projCategory": {
        "isEmpty":"Value is required and can't be empty"
    },
    "projStart": {
      "isEmpty":"Value is required and can't be empty"
    },
    "projEnd": {
      "isEmpty": "Value is required and can't be empty"
    },
    "createdOn": {
      "isEmpty": "Value is required and can't be empty"
    },
    "createdBy": {
      "isEmpty": "Value is required and can't be empty"
    }
  },
  "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
  "title":"Unprocessable Entity",
  "status":422,
  "detail":"Failed Validation"
}

My Browser says this

Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Authorization:Bearer 4ef85a6aea3bdfd5e9a19bd28df145254c6e8133
Connection:keep-alive
Content-Length:73442
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryAPvdSnxwn6DQnYdP
Host:192.168.2.21
Origin:http://localhost:4200
Referer:http://localhost:4200/projectDefinitions/edit/4;mode=Edit;showPage=1;showRows=11;filters=%7B%7D
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
X-HTTP-Method-Override:PUT

------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="projectId"

4
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="projDesc"

Sapiri Gevathu
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="projCategory"

3002
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="projStart"

2017-01-01
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="projEnd"

2017-12-30
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="applSeason"

1
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="projObjectives"

Objective Two
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="projProposal"; filename="AGREEMENT-new.pdf"
Content-Type: application/pdf


------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="createdOn"

2017-09-29 08:48:31
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="createdBy"

user
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="modifiedOn"

2017-10-2 8:2:22
------WebKitFormBoundaryAPvdSnxwn6DQnYdP
Content-Disposition: form-data; name="modifiedBy"

user
------WebKitFormBoundaryAPvdSnxwn6DQnYdP--

Originally posted by @Channad at zfcampus/zf-content-negotiation#89

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions