Oracle APEX 21.2:动态加载禁用文本框触发会话保护错误
我有一个模态表单,点击“Lookup User”按钮时,动态动作会从外部源获取用户信息,并为页面上的页面项设置会话状态。除“username”外,其他所有字段均为禁用状态,但在页面提交(页面流程)时仍需提交以参与DML操作。
动态动作PL/SQL代码
select employee_id ,last_name ,first_name ,email into r_ldap_user from ...; apex_util.set_session_state('P65_EMPLOYEE_ID', r_ldap_user.employee_id); apex_util.set_session_state('P65_FIRST_NAME', r_ldap_user.last_name); apex_util.set_session_state('P65_LAST_NAME', r_ldap_user.first_name); apex_util.set_session_state('P65_EMAIL', r_ldap_user.email);
动态动作能正确加载表单数据,但存在两个问题:
- 在会话窗口中,这些被设置的页面项没有显示会话状态。
- 点击“Save”执行页面提交并处理表单DML(同样通过PL/SQL实现)时,出现session state protection错误(错误提示:Session state protection violation: This may be caused by manual alteration of protected page item P65_EMPLOYEE_ID.)。
我已确认页面项配置:
- Read Only 属性设为“off”
- Disabled 设为“on”
- Send on Page Submit 设为“on”
但问题依旧。我尝试过仅显示、只读等多种字段状态,这是APEX 18.1的Bug吗?我曾查阅过Stack Overflow相关问题。(配置截图显示页面项的Send on Page Submit为Yes,Disabled为Yes)
关于会话窗口不显示状态
APEX会话窗口默认仅展示通过页面提交或URL参数设置的项值,apex_util.set_session_state在动态动作PL/SQL块中设置的状态不会实时同步到窗口显示,但实际上会话状态已被正确设置。你可以在提交流程中直接引用:P65_EMPLOYEE_ID来验证值是否存在,无需纠结窗口显示。
关于Session State Protection错误
这不是APEX Bug,是禁用字段提交时的典型问题:
当页面项设为Disabled时,浏览器会忽略该字段提交,但开启Send on Page Submit后,APEX会生成隐藏字段传递值。若页面项的会话状态保护级别为Checksum Required - Session或更高,隐藏字段提交时未携带正确校验和,就会触发错误。
解决方法三选一:
调整会话状态保护级别
进入页面项的Security属性,将Session State Protection设为Unrestricted。这类后台设置的字段无需前端修改,Unrestricted级别可避免校验和冲突。改用只读字段替代禁用
将字段的Read Only设为“on”,同时开启Send on Page Submit。只读字段会保留提交值,不会被浏览器忽略,也能避开会话状态保护问题。提交时直接从会话状态取值
在DML流程的PL/SQL代码中,不依赖提交的页面项值,直接调用会话状态:insert into your_table (employee_id, first_name, last_name, email) values ( apex_util.get_session_state('P65_EMPLOYEE_ID'), apex_util.get_session_state('P65_FIRST_NAME'), apex_util.get_session_state('P65_LAST_NAME'), apex_util.get_session_state('P65_EMAIL') );这样即使提交时字段值未传递,也能直接使用之前设置的会话状态值。
内容的提问来源于stack exchange,提问作者McRivers

