Testes para existência de âmbito FORM / struct em ColdFusion
-
05-07-2019 - |
Pergunta
Problema: Ao solicitar a WSDL para uma CFC , eu recebo o seguinte erro: FORM variável é indefinido . Acontece nesta linha de código, no método OnRequestStart em Application.cfc
<cfif structKeyExists(form,'resetappvars')>
<cfset OnApplicationStart() />
</cfif>
Se eu solicitar um método específico, ele funciona bem. Eu tenho considerado usando CFPARAM para criar um formulário padrão struct se não existe nenhum, mas que parece ser uma gambiarra e eu se preocupe ele vai realmente criar o formulário struct nas variáveis ??ou este escopo do CFC. Talvez este seja um bug legítima bem?
Nota:. Isto só acontece quando eu solicitar o WSDL, se eu chamar um método diretamente - os executa código como esperado, sem problemas
Update: Application.cfc amostra de código - basta adicionar qualquer CFC para o seu aplicativo e solicitá-lo com ?wsdl
para ver a questão. Este foi testado (e falhou) em ColdFusion 7 e ColdFusion 8.
<cfcomponent output="false">
<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="false" hint="Fires when the application is first created.">
<cfset application.dsn = "my_dsn" />
<cfreturn true />
</cffunction>
<cffunction name="OnRequestStart" access="public" returntype="boolean" output="false" hint="Fires at first part of page processing.">
<cfargument name="TargetPage" type="string" required="true" />
<cfif structKeyExists(form,'resetappvars')>
<cfset OnApplicationStart() />
</cfif>
<cfreturn true />
</cffunction>
</cfcomponent>
Solução
Este cargo de Ben Nadel dá lista detalhada de escopos disponíveis para diferentes tipos de pedidos.
Ao lê-lo, você pode facilmente descobrir que forma escopo não está disponível em determinado contexto, mas URL é.
Outras dicas
Talvez tente adicionar um:
<cfif IsDefined("form")>...</cfif>
em torno do código acima?
Você também pode cfparam
a variável que você está procurando, em seguida, basta mudar a sua lógica um pouco (assumindo resetAppVars é um boolean:
<cfparam name="form.resetAppVars" default="false" />
...
<cfif form.resetAppVars>
<cfset OnApplicationStart() />
</cfif>
Edit:. Eu não tenho certeza se o código acima poderia ser considerado um hack, mas parece CF bastante normal, para mim
Eu ouvi dizer que é apenas uma questão de opinião, mas parece-me que é imprópria para referenciar o seu âmbito formulário dentro de um CFC, porque não há nenhuma garantia de que o escopo formulário estará disponível quando o cfc é invocado e quando o método é chamado. É melhor para garantir que todos os dados que precisa ser disponível para o método é fornecido explicitamente ao seu objeto. Isso pode ser feito através da inclusão de um argumento:
<cfargument name="resetAppVars" type="boolean" required="false" default="false" />
Em seguida, você verificar arguments.resetAppVars, e é sempre definido, mas padrão para falso.
Ou, criando um atributo no seu objeto e criando um método conjunto explícito:
(no topo da sua cfc)
<cfset this.resetAppVars = false />
<cffunction name="setResetAppVars" access="public" returnType="void" output="false">
<cfargument name="flagValue" type="boolean" required="true" />
<cfset this.resetAppVars = arguments.flagValue />
</cffunction>
No caso em que você vai verificar contra this.resetAppVars. Você também pode escopo isso usando localmente <cfset var resetAppVars = false />
como a declaração, o que o torna um atributo privado do seu objeto, e é provavelmente correta, então o código que chama o objeto não pode substituir indevidamente esta variável com um tipo não booleano. Nesse caso, você poderia simplesmente se referem diretamente a resetAppvars em seu teste, em vez de usar este escopo.
Você também pode fazer isso:
<cfif NOT isSoapRequest()>...
e cumpri sua lógica restante dentro daquele pedaço.