Image Upload in Vapor 3 using PostgreSQL

蓝咒 提交于 2020-01-12 14:20:27

问题


I'm following this guys Martin Lasek Tutorials and now i'm at "image upload". It seems that no one has the answer to the question "How do you upload images i Vapor 3"

Db connection is ok, all the other values are saved.

This is mye create method:

    func create(_ req: Request) throws -> Future<Response> {

    return try req.content.decode(Question.self).flatMap { question in
        return question.save(on: req).map { _ in

            return req.redirect(to: "/form")
        }
    }
}

and Model:

final class Question: PostgreSQLModel {

var id: Int?
var questionText: String
var answers: [String]
var theme: String?
var imageName: String?
var imageData: File?

init(id: Int? = nil, questionText: String, answers: [String], theme: String, imageName: String?, imageData: File?) {

    self.id = id
    self.questionText = questionText
    self.answers = answers
    self.theme = theme
    self.imageName = imageName
    self.imageData = imageData
}

}

and Leaf template:

<form action="/save" method="POST" enctype="multipart/form-data" id="upload-form">
<input type="file" accept="image/png,image/jpg" name="image">
<input class="btn btn-success btn-block" type="submit" value="Legg til">
</form>

I know a method for managing files is needed and the raw image bytes to,

But how do i get there?


回答1:


This uses automatic decoding of the multi-part form:

router.get("upload") {
    request -> Future<View> in
    return try request.view().render("upload")
}

struct ExampleUpload: Content {
    let document: File
}

// this saves the file into a Question
router.post(ExampleUpload.self, at:"upload") {
    request, upload -> Future<HTTPResponseStatus> in
    let question = try Question()
    question.imageData = upload.document.data
    question.imageName = upload.document.filename
    return question.save(on:request).transform(to: HTTPResponseStatus.ok)
}

The upload.leaf file is:

<form method="POST" enctype="multipart/form-data">
<input type="file" name="document" />
<input type="submit" value="Send" />
</form>

Using the type File enables the local filename of the uploaded file to be accessed as well as the file data. If you add in the rest of the Question fields to the ExampleUpload structure, you can use the route to capture the whole form's fields.




回答2:


I've managed to get the image data by doing this:

struct ImageRequest: Content {
    var imageData: Data
}

func analyizeImage(_ request: Request) throws -> Future<Response> {
    return try request.content.decode(ImageRequest.self).flatMap(to: Response.self, { [weak self] imageRequest in
        guard let image = NSImage(data: imageRequest.imageData) else {
            throw Abort(.badRequest)
        }

        // Do what you want with your image
    })
}

My form looked like this:

<form method="POST" enctype="multipart/form-data">
    <input type="file" name="imageData" />
    <input type="submit" value="Send" />
</form>



回答3:


In order for req.content.decode(Question.self) to work, your model have to conforms to the Content protocol which is Vapor encapsulation of Codable + other encoding/decoding stuff.

Did you add it to your Question model?

something like that:

extension Question: Content {}


来源:https://stackoverflow.com/questions/51476048/image-upload-in-vapor-3-using-postgresql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!