我已经升级到使用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
您将看到(在我的情况下),尽管params.id是foo ,但第一次尝试渲染cmd.id时显示为null
从这次练习中,我还发现,不指定include-id和target的bindData调用以独占方式失败,并且使用params显式实例化命令对象会导致异常。
我在这里完全不知所措。我尝试过重写getInstanceControllersApi方法来返回一个记录不同bindData调用的包装器,这样我就可以看到发生了什么以及如何控制它,但这并没有告诉我什么。
当我调用新的ExperimentalCommand(params)时,我可以向命令对象添加控制器和操作字段,以防止它出错,但我不应该这样做。Grails文档指出,在调用操作之前,将在命令对象的实例上完成绑定,但在我的情况下,它不是。
谷歌没有发现任何东西,所以很明显,我是第一个不得不处理这个问题的人之一。
问题是我怎么能解决这个问题?
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中的这些形式的数据绑定非常方便,但也不分青红皂白。换句话说,它们将绑定目标对象的所有非瞬态、类型的[my bold]实例属性,包括您可能不希望绑定的属性。