AuthenticationException: Authentication failed, see inner exception
CENÁRIO:
Olá!
De uns tempos pra cá meu Mac (OSX) parou de funcionar a funcionalidade de rodar aplicações “localhost” com HTTPS embutido no ASP.NET Core.
Pra contornar, estava montando o Kestrel com certificado auto assinado gerado por mim mesmo (https://docs.microsoft.com/pt-br/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2#kestrel-options), mas o outro jeito era tão mais fácil e simples que resolvi procurar e há um jeito de resolver! J
ERRO:
Deixando default, e tentando acessar a URL “localhost” com HTTPS obtinha a seguinte mensagem de erro:
fail: Microsoft.AspNetCore.Server.Kestrel[0]
Uncaught exception from the OnConnectionAsync method of an IConnectionAdapter.
System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. —> Interop+AppleCrypto+SslException: Internal error
— End of inner exception stack trace —
SOLUÇÃO:
Para resolver, há um comando do próprio dotnet para corrigir os certificados e voltar a funcionar tudo perfeitamente:
dotnet dev-certs https
No meu mac, não resolveu de primeira. Tive que limpar os certificados antes com este comando:
dotnet dev-certs https –clean
e depois:
dotnet dev-certs https
Pronto!
Tudo funcionando perfeitamente novamente. 🙂
Abraço!
Fazendo Joins com CAML Query
Olá!
Cenário:
O SharePoint 2010 introduziu uma novidade na maneira de realizar queries usando as já conhecidas CAML Queries. Agora podemos utilizar Joins (e campos projetados) em nossas CAML queries, economizando esforço e até ganhando performance nas queries para alcançar alguns objetivos que antes, no SharePoint 2007, não havia o que fazer.
No MSDN encontramos bastante documentação a respeito, mas ainda um tanto confuso. Pelo menos eu achei.
http://msdn.microsoft.com/en-us/library/ee539975.aspx – List Joins and Projections
SOLUÇÃO:
Primeiramente vamos preparar o ambiente que vamos fazer nossos testes.
· Crie duas listas em seu SharePoint, uma lista chamada Eventos (do tipo Personalizada ou Custom List) e outra lista chamada Contatos (do tipo Contatos ou Contacts)
Nas lista de Eventos, crie uma coluna do tipo Loopkup (consulta) para a lista de Contatos, chamada Responsavel (sem acento).
Vá na lista de Contatos e adicione alguns registros:
Volte a lista de Eventos e também adicione alguns registros, associando contatos aos Eventos:
Pronto, agora temos o ambiente preparado. Iremos listar todos os eventos e mostrar o título do Evento, Nome e SobreNome (informação que está na outra lista) com apenas uma única query.
static void Main(string[] args)
{
ShowJoin();
}
private static void ShowJoin()
{
using (SPSite site = new SPSite("http://notebook02/sites/treinamento"))
{
using (SPWeb web = site.OpenWeb())
{
SPQuery query = new SPQuery();
query.Query = @"<OrderBy>
<FieldRef Name='Title' />
</OrderBy>";
query.Joins = "<Join Type='INNER' ListAlias='Contatos'>" +
"<Eq>" +
"<FieldRef Name='Responsavel' RefType='Id'/>" +
"<FieldRef List='Contatos' Name='ID'/>" +
"</Eq>" +
"</Join>";
query.ProjectedFields =
"<Field Name='Nome' Type='Lookup' " +
"List='Contatos' ShowField='FirstName'/>" +
"<Field Name='SobreNome' Type='Lookup' " +
"List='Contatos' ShowField='Title'/>";
query.ViewFields = "<FieldRef Name='Title'/>" +
"<FieldRef Name='Nome'/>" +
"<FieldRef Name='SobreNome'/>";
SPList listaEventos = web.Lists["Eventos"];
SPListItemCollection items = listaEventos.GetItems(query);
if (items.Count > 0)
{
foreach (SPListItem item in items)
{
SPFieldLookupValue dseLastName =
new SPFieldLookupValue(item["SobreNome"].ToString());
SPFieldLookupValue dseFirstName =
new SPFieldLookupValue(item["Nome"].ToString());
Console.WriteLine("Nome do Evento: {0}, SobreNome do Reponsável: {1}, Nome do Responsável: {2}",
item.Title,
dseLastName.LookupValue,
dseFirstName.LookupValue);
}
Console.ReadLine();
}
}
}
}
Explicando:
SPQuery query = new SPQuery();
query.Query = @"<OrderBy>
<FieldRef Name='Title' />
</OrderBy>";
Até aqui normal, a mesma query que sempre utilizamos. Nesse caso, apenas ordenando pelo título do evento.
query.Joins = "<Join Type='INNER' ListAlias='Contatos'>" +
"<Eq>" +
"<FieldRef Name='Responsavel' RefType='Id'/>" +
"<FieldRef List='Contatos' Name='ID'/>" +
"</Eq>" +
"</Join>";
Aqui montamos a condição do Join que iremos fazer com a lista Contatos (lembrando que nossa query roda na lista Eventos).
query.ProjectedFields =
"<Field Name='Nome' Type='Lookup' " +
"List='Contatos' ShowField='FirstName'/>" +
"<Field Name='SobreNome' Type='Lookup' " +
"List='Contatos' ShowField='Title'/>";
Aqui projetamos os campos da lista Contatos na “lista” Eventos. Na verdade, os campos são projetados apenas no SPListItemCollection retornado na query. Damos um alias (Name) para o campo e vinculamos ao nome interno (ShowField) do campo na lista Contatos. Então, nossos itens retornados terão as colunas projetadas Nome e SobreNome, da lista Contatos, juntamente com todas as colunas da lista de Eventos.
query.ViewFields = "<FieldRef Name='Title'/>" +
"<FieldRef Name='Nome'/>" +
"<FieldRef Name='SobreNome'/>";
Aqui explicitamos apenas os campos que queremos retornados na query. Ou seja, a query trará APENAS os campos relacionados abaixo. Bom procedimento quando queremos performance, afinal, por que trazer todos os campos se apenas vamos usar alguns?
Percebam que usei os alias criados anteriormente e não mais o nomes reais da lista Contatos (que seriam Title, para LastName, e FirstName).
Ao mandar rodar, temos:
Campos de outra lista projetados no resultado da query. E o melhor, podemos fazer query na outra lista já nessa mesma query! Exemplo:
query.Query = @"<Where>
<Eq>
<FieldRef Name='Nome' />
<Value Type='Text'>Thiago</Value>
</Eq>
</Where>
<OrderBy>
<FieldRef Name='Title' />
</OrderBy>";
O campo Nome, que usei na query, não “existe” em nenhuma das listas. É o alias, ou campo projetado, criado aqui:
query.ProjectedFields =
"<Field Name='Nome' Type='Lookup' " +
"List='Contatos' ShowField='FirstName'/>" +
"<Field Name='SobreNome' Type='Lookup' " +
"List='Contatos' ShowField='Title'/>";
Vamos testar! De acordo com a Query, é para trazer ordenado pelo título do evento, apenas os eventos que o Nome do responsável seja igual a Thiago.
É isso aí, até mais!
Abraço!
DateTimeControl customizado não carrega estilo
Olá!
Cenário:
Desenvolvendo soluções customizadas para o SharePoint é bem comum utilizar o DateTimeControl (controle do SharePoint) para usuários selecionarem datas em nossos formulários.
Em determinadas situações o calendário não renderiza corretamente. Ele não carrega o estilo e fica bem feio.
ERRO:
Vejam como o calendário fica nessas situações:
SOLUÇÃO:
Para solucionar o problema devemos alterar a página encarregada por renderizar o calendário. No SharePoint, encontramos essa página no caminho:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS
Edite a página iframe.aspx e insira uma referência para carregar o arquivo CSS responsável por aplicar o estilo do calendário.
<link rel="stylesheet" type="text/css"href="/_layouts/1046/styles/datepickerv4.css"/>
NOTA: altere o 1046 para idioma do seu SharePoint. (Ex: 1046 – PT-BR, 1033 – EN-US)
O arquivo ficará parecido com o seguinte:
Salve o arquivo e clique no calendário para ver que ele irá carregar o estilo!
Abraço!