Erro chamando um serviço de repouso WCF usando JSON. Cota de comprimento (8192) excedida
-
20-09-2019 - |
Pergunta
Estou tendo um serviço de repouso no WCF hospedado no IIS usando .NET 4 RC. As chamadas post para o serviço são serializadas usando o JSON. Tudo funciona bem até que o tamanho de um dos datamember (string) seja superior a 8k. Nesse caso, recebo o erro descrito abaixo, indicando que o comprimento do maxstringContentLear foi excedido. O atributo MaxStringContentLength para o endpoint foi aumentado e é lido corretamente no arquivo de configuração.
A configuração da web é:
<services>
<service name="MyServiceServer" >
<endpoint address="http://localhost/MyService" kind="webHttpEndpoint" endpointConfiguration="serviceEndPoint" contract="IMyService">
</endpoint>
</service>
</services>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="serviceEndPoint" maxReceivedMessageSize="2048000" maxBufferSize="2048000" maxBufferPoolSize="0">
<readerQuotas maxStringContentLength="2048000" maxArrayLength="2048000" maxDepth ="65000"/>
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
A interface do iMyService é definida como:
public interface IMyService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/request", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
void MyMehod(<Class Type> obj);
}
A mensagem de erro completa é:
“O servidor encontrou um erro processando a solicitação. A mensagem de exceção é 'houve um erro deseralizando o objeto do tipo. A cota máxima de comprimento do conteúdo da string (8192) foi excedida ao ler dados XML. Esta cota pode ser aumentada alterando a propriedade MaxStringContentLength no objeto XmldictionaryReaderquotas usado ao criar o leitor XML. '. Consulte os logs do servidor para obter mais detalhes. The exception stack trace is: at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName) at System.ServiceModel. Dispatcher.singleBodyPearameterMessageForMatter.DeSerializeReQuest (mensagem da mensagem, objeto [] parâmetros) em System.Servicemodel.dispatcher.demultiplexingDispatchMessageFormatter.DeSerializeQuest (Mensagem, objeto [] parâmetros) em sistemas.ServicemodelEl.DeSisp.DisMismEnMIST.DISMIST.DISMIST.DISMIST.DISMISPEMISTEMISTERIMISPEMISTEMISTERIMISTERMISPEMISTERIMISTERMISTERIMISTERMISTERIMISTERIMISTERIMISTERIMENTESMESTEMISTEMISTEMISTEMISTOS DO SISTEMISTEMIST.DISMISTS (Mensagem, objeto [] parâmetros) em system.servicemodel.dispatcher.dispatchoperationRuntime.DeserieRialImputs (Messagerpc & rpc) em system.servicemodel.dispatcer.dispatchOperationRuntime.invokebegin (messagerpc & rpc) em sistemas.ServicemOmodelEnTeL.InvokeBegin (Messagerpc & rpc) em sistemas.ServicemOmodelEnTenMent.InvokeBegin (MessagerPc & rpc) em sistemas.ServicemOmodelEngenMent.Invokebegin (Messagerpc & rpc) em System.ServicemOmodelMel cemodel.dispatcher.immutabledispatchRuntime.processmessage31 (MessagerPC & RPC) em System.servicemodel.dispatcher.messagerpc.process (boolean iSoperationContetSet) ”
Solução
Isso funciona, apenas certifique -se de ter um URL absoluto completo como seu endereço de terminal. Se você ficar astuto e tentar usar um caminho relativo, ou se omitir .svc, ele bombardeará com o estranho erro de cota do leitor assim que a solicitação ficar muito grande -
Eu arquivaria isso em um bug para o WCF porque:
- URLs relativos devem ser proibidos (e uma exceção apropriada lançada)
ou
- A cota do leitor deve funcionar com caminhos relativos também
Outras dicas
Insira em seu web.config:
<configuration>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingConfig">
<readerQuotas maxStringContentLength="2048000" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
e inserir atributo bindingConfiguration = "webhttpbindingconfig" em seu terminal
Eu tive problemas semelhantes, mas com .NET 3.5
Não tive problemas no log do servidor, então o problema estava no cliente.Parece que a configuração com os valores máximos aumentou não foi lida e usada...
Então, resolvi passar o nome do endpoint explicitamente no construtor do WebChannEflactory, usando outra sobrecarga.
FOI:
WebChannelFactory<IWKRestTest> factory = new WebChannelFactory<IWKRestTest>(new Uri(XXX));
factory.Credentials.UserName.UserName = K_USERNAME;
factory.Credentials.UserName.Password = K_PASSWORD;
IWKRestTest proxy = factory.CreateChannel();
É:
WebChannelFactory<IWKRestTest> factory = new WebChannelFactory<IWKRestTest>("IWKRestTestService");
E no app.config, está:
O URI é indicado no nó do endpoint, mas você também encontra o BindingConfiguration e assim por diante, para que todos os novos limites aumentados agora funcionem.