Aug 17, 2012

Modificar Programaticamente Propriedade ReaderQuotas de um Endpoint - WCF


Estava com um problema no seguinte cenário:

Tenho um WCF, onde faço o "SelfHosting" por um Windows Service. Os dados doendereço eu coloco dinamicamente.

Os arquivos que eu iria enviar para o WCF passavam facilmente os 16Kb padrões da configuração.

Para isso utilizei o seguinte código para adicionar no endpoint que adicionei programaticamente (pelo código compilado, não pelo app.config)







                var endpoint = serviceHostImport.AddServiceEndpoint(typeof(IImportFileService), 
                                        MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

                Binding binding = endpoint.Binding;

                XmlDictionaryReaderQuotas quotas = new XmlDictionaryReaderQuotas();
                quotas.MaxStringContentLength = int.MaxValue;
                quotas.MaxArrayLength = int.MaxValue;
                quotas.MaxBytesPerRead = int.MaxValue;
                quotas.MaxDepth = 64;
                quotas.MaxNameTableCharCount = int.MaxValue;

                binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, quotas, null);

                serviceHostImport.Open();







Repare que a propriedade é adicionada via Reflection.


com isso é possível modificar programaticamente a propriedade ReaderQuotas  do binding de um endpoint WCF para o máximo possível.

Abraços
Rafael

Jul 1, 2012

Como gerar xml à partir de uma classe com atributos customizados





Bom, esses dias precisei criar um XML a partir de uma classe, com os valores das propriedades do objeto.


Realmente existem diversos meios de se fazer isso facilmente, como serialização, entre outros.O problema era que apenas alguns atributos seriam adicionados, não a classe inteira e ainda por cima com nomes diferentes. Por exemplo:

Nome da propriedade "Nome" e nome do atributo xml era "nome_usuario".

Para isso criei um atributo customizado:





  [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
    public class AtributoXml: Attribute
    {
        private string _nomeXml;
        public string NomeXml
        {
            get { return _nomeXml; }
            set { _nomeXml = value; }
        }
    }





Não esquecer de colocar o "AttributeTargets.Property" , já que assim é possível colocar nas propriedades e não apenas na classe.




No passo seguinte usaremos reflection para acessar dados do atributo e da classe, por isso não esqueça de referência  à "System.Reflection;"

Para conseguir pegar o valor do atributo ,utiliza-se o seguinte códig


var campos = tipo.GetProperties(BindingFlags.Public | BindingFlags.Instance);//Obtém propriedades
foreach (var c in campos)//percorre todos os campos
            {
                  var keys = c.GetCustomAttributes(typeof(AtributoXml), true); //Obtém atributo 
                  nomeCampo = ((AtributoXmlBaseMwl)(keys[0])).NomeXml;

            }


Aplicação real:


public virtual string CriarXml()
        {
            string xmlValue = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>
            <config xmlns=\"http://www.w3schools.com\" 
            xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
            xsi:schemaLocation=\"http://www.w3schools.com\" ><item>";
            var tipo = typeof(BaseMwlItem);

            var campos = tipo.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var c in campos)
            {
                // lista atributos do campo
                string nomeCampo = string.Empty;
                var keys = c.GetCustomAttributes(typeof(AtributoXmlBaseMwl), true);
                if (keys.Length == 1 && keys[0] is AtributoXmlBaseMwl)
                    nomeCampo = ((AtributoXmlBaseMwl)(keys[0])).NomeXml;

                if (!string.IsNullOrEmpty(nomeCampo))
                {
                    object valor = c.GetValue(this, null);
                    string valorPropriedade = string.Empty;
                    if (valor is DateTime)
                    {
                        if (nomeCampo.ToLower().Contains("time"))
                            valorPropriedade = ((DateTime)valor).ToString("hh:mm:ss");
                        else
                            valorPropriedade = ((DateTime)valor).ToString("yyyy-MM-dd");
                    }
                    else
                    {
                        valorPropriedade = valor.ToString();
                    }

                    xmlValue += string.Format("<{0}>{1}</{2}>", nomeCampo, 
                                valorPropriedade, nomeCampo);
                }
            }

            return xmlValue + "</item>";

        }




Pronto, faça o que quiser com seu XML.

Abraços
Rafael Campana


Jun 28, 2012

Windows Service Acessando Unidade de Rede

Estava com o seguinte problema:

Um serviço windows que desenvolvemos precisava acessar uma pasta localizada em uma unidade de rede, o que não estava acontecendo, mesmo passando a unidade na configuração.

Depois de alguns testes e pesquisa cheguei à seguinte conclusão.
O problema estava na forma que o drive é acessado.

É o seguinte:
O drive mapeado é específico por usuário e o serviço, por padrão , utiliza outro usuário para rodar/executar (local system), não o que está logado.

Isso quer dizer que o usuário do serviço nã conhece o driver, por exemplo "Z:", então, pesquisando, encontrei as seguintes soluções:

1ª) Mais fácil, mas que não consegui fazer funcionar:
Alterar o logon do serviço para um usuário que tenha o "Z:" mapeado corretamente, simples, não? Pena que não funcionou comigo. Mas, pode-se tentar, facinho de fazer e teve gente que falou que funciona.

2ª) que funcionou lol, Passos:
1: Parar o serviço
2: Baixar este programa: http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx (utilzado para executar o cmd.exe com o usuário local system)
3: Executar o cmd.exe como administrador
4: Executar o comando "psexec -i -s cmd.exe" (abre o cmd.exe como o usuário local system)
5: Abrirá uma nova tela do cmd.exe
5: Para ter certeza que o usuário é o local system, execute o comando "whoami". O retorno deve ser "nt authority\system"
6: Agora que você sabe que o usuário é o mesmo do serviço, execute o comando de mapear unidade a partir do prompt "net use" (a sintaxe é : net use\\\/persistent:yes . Exemplo: "net use Z: \\srvdesenv-05\Teste /persistent:yes
7:Vai perdir o usuário, você coloca
8: Vai pedir senha, você coloca
9:Inicie o Serviço

Basicamente é isso ae... mas podem existir outras variáveis, principalmente de permissão.

Referências:
http://stackoverflow.com/questions/182750/how-to-map-a-network-drive-to-be-used-by-a-service

http://serverfault.com/questions/91797/windows7-the-specified-network-password-is-not-correct-when-the-password-is

Abraços
Rafael Campana

Feb 1, 2012

Erro ao conectar banco de dados "ORA-06413: Connection not open"

Boa Noite Pessoal,


Bom, semana passada eu e uma amigo (Renê) "apanhamos" muito para conectar uma aplicação com nhibernate e em um banco de dados Oracle 10g.


Como eu sou muito legal: E o problema era PARÊNTESES "( )", isso mesmo, o client do oracle para .net .


O erro que a aplicação retornava era: 




ORA-06413: Connection not open



Isso quando eu tentava conectar  uma aplicação 32 bits (x86) em uma máquina 64 bits (no caso, windows 2008 64 bits, x64) em uma base de dados oracle 10g

A solução?
Simples: Altere a pasta da aplicação para outra sem parênteses.


Exemplo:

Troque isto:


C:/Arquivos de Programs (x86)/PastaAplicacao


Por isto:




C:/Aplicacoes/PastaAplicacao  --SEM PARÊNTESES


Por hoje é só, espero ter ajudado!


Abraços

Rafael
 



Dec 21, 2011

Erro ao criar proxy com nHibernate - Creating a proxy instance failed


Essa semana tive um problema , onde acabei gastando algumas horas para descobrir.


O problema era o seguinte, ao atualizar uma entidade,o nhibernate se perdia inteiro para contruir o proxy e gerava uma exceção.


o exceção era a seguinte:



Mensagem de exceção
NHibernate.HibernateException: Creating a proxy instance failed 

Inner ExceptionSystem.ArgumentNullException: Value cannot be null.Parameter name: type  


o que não dizia muita coisa, já que erro para criar proxy pode ser uma infinidade de problemas.


Pesquisando bastante, acabei me deparando por algumas pessoas comentando um possível Bug no Nhibernate  utilizando o proxy factory LinFu, exatamente como eu, mas ignorei pois eram poucos os lugares e ninguém confirmava o problema.

Por fim, Acabei vasculhando todas as entidades, e acabei  achando um método com parâmetro out, que havia sido alterado por um outro colega meu, alterei o método para não precisar do parâmetro e o sistema voltou a funcionar correamente.

Não sei se este problema já foi corrigido em novas versões, mas tente isto, talvez resolva.

A assinatura do método era parecido com a seguinte:


PROBLEMA:

public void VerificarUsuario(AcessoUsuario acessoUsuario, out string mensagemErro)



simplismente alterei para que a mensagem de erro fosse disparada diretamente do método:


SOLUÇÃO

public void VerificarUsuario(AcessoUsuario acessoUsuario)


Espero ter ajudado.

Abraços

Nov 16, 2011

Ajustar IFrame de acordo com conteúdo

Há algum tempo tive o problema de redimensionar um iframe de acordo com o conteúdo , conforme o conteúdo aumenta, o iframe aumenta também.

Para realizar esta façanha, seguir os seguintes passos:

Na página conteúdo ( que ficará dentro do iframe )

Colocar o seguinte código.



<body onload="atualizaIframe();">



criar uma div com o nome "container" , para assim , conseguir pegar a altura total, para assim, alterar o height do iframe da página pai.

função JavaScript:



function atualizaIframe() {
  var tamanho = document.getElementById("container").offsetHeight;
  parent.document.getElementById("ifrm").style.height = tamanho;  
}




Na página pai (parent), onde ficará o iframe

colocar o código do iframe.Não esquecer de setar a propriedade scrolling para "no" e definir o id do iframe para "ifrm" no caso da função javascript atual, se quiser alterar o nome, alterar na função também



<iframe width="100%" scrolling="no" height="600px" frameborder="0" id="ifrm"
allowtransparency="true" heigth="100%" marginwidth="10" marginheight="0"
style="padding: 0pt; margin: 0pt; height: 10111px;" src="http://paginafilha/conteudo">
</iframe>



 Pronto, de acordo com o crescimento do conteúdo, a altura do iframe aumenta também.




 

Nov 10, 2011

Foco inicial em controle

Hoje tive um problema simples mas que gastei algum tempo pesquisando como solucionar, como sou muito legal, colocarei a solução aqui.


Ao tentar colocar foco em algum controle, como por exemplo um TextBox, o método Focus (tanto no FormLoad quanto no construtor, do controle retornava falso e a propriedade CanFocus também.Não sei porque  isto ocorre, talvez porque o controle não foi completamente contruido, mas a solução é a seguinte:

Colocar chamar o metodo Focus no Evento FormShown , do formulário.


private void Form_Shown(object sender, EventArgs e)
{
    textBox1.Focus();
}


Créditos para onde eu encontrei a solução:

Tópico no StackOverflow