免责声明:在这里使用PlayFramework 2.6.0-M4!
我显示一个表单,并希望添加额外的约束,禁止某些字符串用于给定字段。
现在我有两个问题:
def create() = Action(parse.form(createUserForm))
{
implicit request =>
val formData: CreateUserData = request.body
if(validate(formData).isDefined)
{
userRepository.create(formData.name, formData.dummy)
Ok(s"Here should go success, if user was created: $formData")
} else {
BadRequest("No means no!")
}
}
case class CreateUserData(name: String, dummy: Boolean)
private val createUserForm = Form(
mapping(
"name" -> text,
"dummy" -> boolean
)(CreateUserData.apply)(CreateUserData.unapply)
verifying("Failed form constraints!", fields => fields match
{
case data => validate(data).isDefined
})
)
private def validate(formData: CreatUserData): Option[CreatUserData] =
{
ReservedWords.filter(
_.equalsIgnoreCase(formData.name)
).isEmpty match
{
case true => Some(formData)
case false => None
}
}
1)Ok(s"Here should go success, if user was created: $formData").as("text/html")
适用于提供的数据有效的情况,但是如果用户输入了禁止的名称:
a)没有创建用户(好)
b)BadRequest("No means no!")
永远不会被退回! (虽然我得到一个http 400响应,只是空的)
我不明白为什么b)发生。
此外,我想关注https://www.playframework.com/documentation/2.6.x/ScalaForms
而是编写如下代码:
def create() = Action(parse.form(createUserForm))
{
implicit request =>
createUserForm.bindFromRequest.fold(
formWithErrors =>
{
BadRequest("Errors: " + formWithErrors.errors).as("text/html")
},
formData =>
{
userRepository.create(formData.name, formData.dummy)
Redirect(s"/")
}
)
}
但遗憾的是,这会导致每个帖子请求出错,即使是那些完全有效的错误:
错误:列表(FormError(名称,列表(error.required),列表()))
我做错了什么?
编辑:为了澄清“总有效请求”的含义,我举一个关于错误返回的示例。
name=Teolha&dummy=true
以邮寄请求的形式发送。
实际上我输入的内容并不重要,但(渲染)表单的HTML5部分确保我必须输入内容。如果Ok
列表中有任何 NOT ,则ReservedWords
BadRequest
edit2:可能是因为默认过滤器?
那些在游戏中运行2.6:
play.filters.csrf.CSRFFilter
play.filters.headers.SecurityHeadersFilter
play.filters.hosts.AllowedHostsFilter
我问,因为我不在这里使用Twirl(但是ScalaTags)来渲染表单!所以也许我错过了一些隐含的东西,旋转实现会覆盖(一个令牌或什么)?
答案 0 :(得分:1)
这是正确的行为:
https://playframework.com/documentation/2.6.0-M4/ScalaForms
val userPost = Action(parse.form(userForm)) { implicit request =>
在失败的情况下,默认行为是返回空的BadRequest响应。
接下来:
您可以使用自己的逻辑覆盖此行为。例如,以下代码完全等同于使用bindFromRequest和fold的前一个代码。
val userPostWithErrors = Action(parse.form(userForm, onErrors = (formWithErrors: Form[UserData]) => {
implicit val messages = messagesApi.preferred(Seq(Lang.defaultLang))
BadRequest(views.html.user(formWithErrors))
})) { implicit request =>
val userData = request.body
val newUser = models.User(userData.name, userData.age)
val id = models.User.create(newUser)
Redirect(routes.Application.home(id))
}
在你的情况下
在您的代码中调用验证之前, Action(parse.form(createUserForm))
会调用验证(if(validate(formData).isDefined)
是多余的)。因此它调用验证,验证不成功并且播放返回空的错误请求。
修复: onError
函数的parse.form
处理程序中的进程错误。即Action(parse.form(createUserForm, onErrors = ...
第二个问题
您调用Action(parse.form(createUserForm))
- 它处理表单,然后您调用createUserForm.bindFromRequest
但表单已经处理完毕,因此您获得了一个空表单。这也是正确的。
修复:删除parse.form(createUserForm)
,因此您必须只有Action()