0

我已经从 Grails 1.3.6 升级到使用 Grails 2.1.1,并且一些正在工作的命令对象不再从请求参数中获取数据绑定。

我创建了一个实验控制器来重现该问题:

package my.controllers

import troubleshooting.*

class ExperimentalController {


    def toggle(ExperimentalCommand cmd){
        render "<pre>${this.properties}</pre>"
        render "<h3>Raw</h3>The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"
        bindData(cmd,params)//not even this works wtf?
        render "<h3>bindData(cmd,params)</h3>The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"
        cmd = new ExperimentalCommand()
        render "<h3>New Cmd</h3>The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"
        cmd = new ExperimentalCommand(params)
        render "<h3>New Cmd binding constructor</h3>The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"
        bindData(cmd,params,[include:["id","target"]])
        render "The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"

    }
}
class ExperimentalCommand{
    def id,target,action,controller

}

如果你执行:

grails 运行应用程序

有了它,然后转到:

http://localhost:8080/YourApp/experimental/toggle/foo?target=bullseye&cmd.target=whatever

您会看到(在我的情况下)第一次尝试渲染 cmd.id 将其显示为 null,尽管 params.id 是 foo

从这个练习中,我还发现未指定包含 id 和目标的 bindData 调用完全失败,并且使用参数显式实例化命令对象会导致异常。

我在这里完全不知所措。我已经尝试过诸如覆盖 getInstanceControllersApi 方法以返回一个包装器,该包装器记录不同的 bindData 调用,这样我就可以看到发生了什么以及如何控制它,但什么也没告诉我。

我可以将控制器和操作字段添加到命令对象,以防止它在调用 new ExperimentalCommand(params) 时出错,但我不应该做任何 Grails 文档声明绑定将在实例上完成的操作调用操作之前的命令对象,但在我的情况下它不是。

谷歌没有发现任何东西,所以显然我是第一个必须处理这个问题的人之一。

问题是我该如何解决这个问题?

4

1 回答 1

1

1.3.6 和 2.x 之间的数据绑定机制发生了各种变化,我要尝试的第一件事是为命令对象属性提供正确的类型,而不仅仅是def

class ExperimentalCommand{
    String id
    String target
    String action
    String controller
}

用于数据绑定的 Grails 2.1.1 文档new CommandObject(params)讨论了数据绑定的形式和obj.properties = params形式,并声明

Grails 中的这些数据绑定形式非常方便,但也是不分青红皂白的。换句话说,它们将绑定目标对象的所有非瞬态、类型化 [我的粗体]实例属性,包括您可能不想绑定的那些。

于 2012-11-20T16:44:56.390 回答