martini-contrib / binding

Martini handler for mapping and validating a raw request into a structure.
MIT License
140 stars 47 forks source link

My file upload isn't working? #26

Closed kristofer closed 10 years ago

kristofer commented 10 years ago

Am trying to use the README's example of a simple form with a file in it.

type UploadForm struct {
    Title       string                `form:"title"`
    Description string                `form:"description"`
    FileUpload  *multipart.FileHeader `form:"fileUpload"`
}

and then the service routine...

    m.Post("/upload", binding.MultipartForm(UploadForm{}), uploadHandler(uf UploadForm, r render.Render) {
        log.Println("Upload Form: ", uf)
        s := fmt.Sprintf("Posted an Upload: %v / %v \n", uf.Title, uf.Description)
        r.HTML(200, "upload_success", s)
    })

but uf, the form struct is always Nil.

Any ideas? Any ideas on how to fix?

mholt commented 10 years ago

Are there any errors generated? Have your handler take a binding.Errors argument and see if it has anything in it.

kristofer commented 10 years ago

no errors.

    m.Post("/upload", binding.MultipartForm(UploadForm{}), func(uf UploadForm, r render.Render, e binding.Errors) {
        log.Println("Upload Form: ", uf)
        //file, err := uf.FileUpload.Open()
        //title := uf.Title
        //desc := uf.Description
        s := fmt.Sprintf("Posted an Upload: %v / %v e: %v \n", uf.Title, uf.Description, e)
        r.HTML(200, "upload_success", s)
    })

is what I did. Did I add the binding.Errors right?

mholt commented 10 years ago

Is the whole form struct (uf) nil or only the FileUpload field nil? I take it your first code was producing a panic, right (manifested as a 500 response)?

Take a look at file_test.go which asserts correct behavior of file uploads (I think so, anyway!) -- the tests kind of show how to use the code.

If that's still not helping, try pasting a sample request you're actually trying here and maybe I can try to reproduce it. The raw HTTP request would be good! (use a small file)

kristofer commented 10 years ago

there was a 500 at first, now the uf struct has empty fields (both title and description are "" and the fileUpload is nil) The form I am posting has the ids set to the name in form: section of the struct.

<form action="" method="POST" role="form" enctype="multipart/form-data">
  <div class="form-group">
    <label for="title">Title</label>
    <input type="text" class="form-control" id="title" placeholder="Title">
  </div>
  <div class="form-group">
    <label for="description">Description</label>
    <input type="text" class="form-control" id="description" placeholder="description...">
  </div>
  <div class="form-group">
    <label for="fileUpload">File to Upload...</label>
    <input type="file" id="fileUpload">
    <p class="help-block">Click here to pick a file to upload from your computer.</p>
  </div>
  <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-upload"></span></button>
</form>

and the struct again is

type UploadForm struct {
    Title       string                `form:"title"`
    Description string                `form:"description"`
    FileUpload  *multipart.FileHeader `form:"fileUpload"`
}

puzzling...

mholt commented 10 years ago

Well the fields have no name attribute. What is the raw HTTP request? I bet your form is being submitted empty, or at least, with each field nameless.

kristofer commented 10 years ago

I meant that the id of the form's <input matched the 'form:"title"' field in the struct.

And yes, the form being posted is blank.

2014/05/02 15:00:21 Req:  &{POST /upload HTTP/1.1 1 1 map[Connection:[keep-alive] Content-Length:[44] Accept:[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8] Origin:[http://localhost:3000] Content-Type:[multipart/form-data; boundary=----WebKitFormBoundaryLsCXNvECjPUIveAm] Referer:[http://localhost:3000/upload] Accept-Encoding:[gzip,deflate,sdch] Accept-Language:[en-US,en;q=0.8] Cache-Control:[max-age=0] User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36] Cookie:[__atuvc=6%7C8; dev_appserver_login="test@example.com:False:185804764220139124118"]] 0xc2100b5c90 44 [] false localhost:3000 map[] map[] 0xc2100ba5d0 map[] [::1]:53430 /upload <nil>}

This is really simplistic, isn't it?

mholt commented 10 years ago

Like I said, your fields are missing name attributes on your form. Names are sent with the form, IDs are only used in the browser. Please read up on the differences and how to set up HTML forms with input tags.

kristofer commented 10 years ago

And, indeed, you are correct. Add name= just like id= to each of the inputs; it was simplistic. Thanks, sorry to bother you.

mholt commented 10 years ago

No problem! You just scared me for a minute since I finally got this thing 99% under test... haha... if it wasn't working I'd be very worried... Glad you fixed it :+1: