如何使用Yesod将文件上传到服务器

8

我正在尝试编写一个表单,允许用户将文件上传到我的服务器。 我看到Yesod使用fileAFormReq实现了这样的功能,但无法使其正常工作,并遇到编译错误,其中最新的错误是: "No instance for (RenderMessage MySite t)" 非常感谢提供任何使用它的简化示例。 谢谢, Uri


嗨Uri,以防万一,我写了一篇关于如何编写完整文件上传的博客文章(提供上传文件服务,在Yesod中引用它们并删除它们)https://ersocon.net/blog/2017/2/18/file-uploads-with-yesod - Alebon
1个回答

13

2012年9月13日更新:

有一个官方维护的文件上传帮助页面,在这里


搜索函数fileAFormReq给我带来了这个例子

我制作了一个只包含相关部分的最小版本。

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
import Yesod.Core
import Yesod.Form
import Yesod.Form.MassInput
import Control.Applicative
import Data.Text (Text, pack)
import Network.Wai.Handler.Warp (run)
import Data.Time (utctDay, getCurrentTime)
import qualified Data.Text as T
import Control.Monad.IO.Class (liftIO)

mkYesod "HelloForms" [parseRoutes|
/file FileR GET POST
|]

data HelloForms = HelloForms

instance RenderMessage HelloForms FormMessage where
    renderMessage _ _ = defaultFormMessage

instance Yesod HelloForms where
    approot _ = ""


main = toWaiApp HelloForms >>= run 3000

fileForm = renderTable $ pure (,)
    <*> fileAFormReq "Required file"
    <*> fileAFormOpt "Optional file"

getFileR = do
    ((res, form), enctype) <- runFormPost fileForm
    defaultLayout [whamlet|
<p>Result: #{show res}
<form method=post enctype=#{enctype}>
    <table>
        ^{form}
    <tr>
        <td>
            <input type=submit>
|]

postFileR = getFileR

runhaskell 运行这个,然后在你的浏览器中访问 http://localhost:3000/file

希望这能有所帮助。 :)


编辑:

哦等等,显然你漏掉了些什么。正如编译错误所说,你的 Foundation 缺少一个 RenderMessage 实例。

我知道最近的国际化工作已经稍微改变了 forms 包。如果你正在使用最新版本的 Yesod,请查看 这里

我贴出的代码使用旧版本的非国际化(默认为英语)的 yesod-forms 包。


2
谢谢。缺少实例错误实际上是我没有正确使用fileAFormReq的副作用(导致ghc期望它具有另一个RenderMessage实例,而不仅仅是您指出的那个,这非常令人困惑)。无论如何,现在它完美地工作了,所以谢谢! - Uri Barenholz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接