8
respostas

Campo de busca não retorna valor

Em outro tópico que fiz sobre inserir valores nulos no banco por um arquivo json, alterei o modelo retirando os [Required] e fazendo uma nova migração, esse processo funcionou perfeitamente, porem quando realizo alguma pesquisa ele retorna um erro, lembrando que antes funciona normalmente a pesquisa porem com campos vazios em vez de nulos.

NullReferenceException: Object reference not set to an instance of an object.

lambda_method(Closure , Contato )
System.Linq.Utilities+<>c__DisplayClass1_0<TSource>.<CombinePredicates>b__0(TSource x)
System.Linq.Enumerable+WhereEnumerableIterator<TSource>.MoveNext()
Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider._TrackEntities<TOut, TIn>(IEnumerable<TOut> results, QueryContext queryContext, IList<EntityTrackingInfo> entityTrackingInfos, IList<Func<TIn, object>> entityAccessors)+MoveNext()
Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider+ExceptionInterceptor<T>+EnumeratorExceptionInterceptor.MoveNext()

AspNetCore.Views_Agenda_Index.ExecuteAsync() in Index.cshtml
-
            </thead>
        </table>
    </div>
    <div class="tbl-content">
        <table cellpadding="0" cellspacing="0" border="0"  class="table table-striped table-bordered">
            <tbody>
                @foreach (var contato in Model)
                {
                    <tr>
                        <th>@contato.Nome</th>
                        <td>@contato.Unidade</td>
                        <td>@contato.Departamento</td>
                        <td>@contato.Telefone</td>

Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ActionContext actionContext, IView view, ViewDataDictionary viewData, ITempDataDictionary tempData, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result)
Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync<TFilter, TFilterAsync>()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
8 respostas

Oi Thiago, tudo bem?

Esse projeto é o mesmo do curso, ou você está trabalhando no seu próprio projeto? Quero saber para poder reproduzir o problema. Você só removeu o atributo [Required] e passou a gerar essa exceção, ou fez mais alguma alteração no projeto?

Tudo sim e com você Marcelo?

Esse é meu próprio projeto, mas estou fazendo com base ao curso, mesma estrutura. Estava funcionando antes com campo valores em " " como no exemplo a baixo:

{
    "name": "Eric",
    "office": "MZAE",
    "department": "Projetos",
    "telephonenumber": "+55 4003 0000",
    "fax": "",
    "mail": "eric@email.com.br"
  }

porem esse Jason era convertido de um arquivo CSV, alterei a forma que o Jason era criado, puxando os dados diretamente do servidor, nisso todo campo não preenchido que estava com " " foi alterado para null como exemplo abaixo:

{
        "name":  "Eric",
        "office":  "MZAE",
        "department":  "Projetos",
        "telephonenumber":  "+55 4003 0000",
        "fax":  null,
        "mail":  "eric@email.com.br"
    }

AgendaController:

namespace MizuAgenda_Core.Controllers
{
    public class AgendaController : Controller
    {        
        private readonly IContatoRepository contatoRepository;

        public AgendaController(IContatoRepository contatoRepository)
        {
            this.contatoRepository = contatoRepository;
        }
        public IActionResult Index(string busca)
        {
            var contato = from c in contatoRepository.GetContatos(busca)
                          where c.Unidade != null & c.Departamento != "TI"
                          & c.Departamento != "TERCEIRO"
                          orderby c.Nome ascending
                          select c;
            return View(contato);
        }
    }
}

AgendaModel:

namespace MizuAgenda_Core.Models
{
    public class AgendaModel
    {
        public class BaseModel
        {
            [DataMember]
            public int Id { get; protected set; }
        }
        public class Contato : BaseModel
        {
            public Contato()
            {

            }

            public string Nome { get; private set; }

            public string Unidade { get; private set; }

            public string Departamento { get; private set; }

            public string Telefone { get; private set; }

            public string Ramal { get; private set; }

            public string Email { get; private set; }

            public Contato(string name, string office, string department, string telephonenumber, string fax, string mail)
            {
                this.Nome = name;
                this.Unidade = office;
                this.Departamento = department;
                this.Telefone = telephonenumber;
                this.Ramal = fax;
                this.Email = mail;
            }
        }
    }
}

ContatoRepository:

namespace MizuAgenda_Core.Repositories
{
    public class ContatoRepository : BaseRepository<Contato>, IContatoRepository
    {
        public ContatoRepository(ApplicationContext contexto) : base(contexto)
        {
        }

        public IQueryable<Contato> GetContatos(string busca)
        {
            if (!string.IsNullOrEmpty(busca))
            {
                return dbSet.Where(s => s.Nome.ToLowerInvariant().Contains(busca.ToLowerInvariant())
                || s.Unidade.ToLowerInvariant().Contains(busca.ToLowerInvariant())
                || s.Departamento.ToLowerInvariant().Contains(busca.ToLowerInvariant())
                || s.Telefone.Contains(busca)
                || s.Telefone.Contains(busca)
                || s.Email.ToLowerInvariant().Contains(busca.ToLowerInvariant()));
            }

            return dbSet;
        }

        public void SaveContatos(List<DadosContatos> dadoscontatos)
        {
            foreach (var dado in dadoscontatos)
            {
                if (!dbSet.Where(d => d.Nome == dado.name).Any())
                {
                    dbSet.Add(new Contato(dado.name, dado.office, dado.department, dado.telephonenumber, dado.fax, dado.mail));
                }
            }
            contexto.SaveChanges();
        }
    }
    public class DadosContatos
    {
        public string name { get; set; }
        public string office { get; set; }
        public string department { get; set; }
        public string telephonenumber { get; set; }
        public string fax { get; set; }
        public string mail { get; set; }
    }
}

Marcelo, consegue me ajudar?

Oi Thiago, estou fazendo uns testes para simular este problema agora.

Thiago, você pode postar o código completo da view aqui? Pelo jeito, o erro na linha logo após <td>@contato.Telefone</td>.

Segue o código, obrigado pelo apoio.

@{
    ViewData["Title"] = "Contatos";
}

@model IQueryable<Contato>;

@using static MizuAgenda_Core.Models.AgendaModel;


    <div class="container">
        <div class="text-center">
            <p>
                <h2>Busca Contato</h2>
            </p>
        </div>
        <form asp-controller="Agenda" asp-action="Index">
            <div class="form-group">
                <div class="input-group">
                    <input type="text" class="form-control" name="busca" placeholder="Busque por Nome, Unidade, Departamento, Telefone, Ramal e Email.">
                    <div class="input-group-btn">
                        <button type="submit" class="btn btn-default">
                            <i class="glyphicon glyphicon-search"></i>
                        </button>
                    </div>
                </div>
            </div>
        </form>
    </div>

<section class="container">
    <div class="tbl-header">
        <table>
            <thead>
                <tr>
                    <th scope="col">NOME</th>
                    <th scope="col">UNIDADE</th>
                    <th scope="col">DEPARTAMENTO</th>
                    <th scope="col">TELEFONE</th>
                    <th scope="col">RAMAL</th>
                    <th scope="col">EMAIL</th>
                </tr>
            </thead>
        </table>
    </div>
    <div class="tbl-content">
        <table cellpadding="0" cellspacing="0" border="0"  class="table table-striped table-bordered">
            <tbody>
                @foreach (var contato in Model)
                {
                    <tr>
                        <th>@contato.Nome</th>
                        <td>@contato.Unidade</td>
                        <td>@contato.Departamento</td>
                        <td>@contato.Telefone</td>
                        <td>@contato.Ramal</td>
                        <td>@contato.Email</td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
</section>

Oi Thiago

Suspeito que o problema seja na hora de obter um valor nulo dentro um elemento da query (Contato.Ramal).

            var contato = from c in contatoRepository.GetContatos(busca)
                          where c.Unidade != null & c.Departamento != "TI"
                          & c.Departamento != "TERCEIRO"
                          orderby c.Nome ascending
                          select c;
            return View(contato);

Vamos testar o seguinte:

1) Retorne uma lista no lugar de uma query:

 return View(contato.ToList());

2) Troque o tipo do Model na view:

@model IEnumerable<Contato>;

O que acha?

Realmente deve ser na hora de receber valores nulos, isso em qualquer campo. Não me adiantaria muito retirar esses filtros retornando uma lista, pois alteramos isso para uma IQueryable

public IQueryable<Contato> GetContatos(string busca)
        {
            if (!string.IsNullOrEmpty(busca))
            {
                return dbSet.Where(s => s.Nome.ToLowerInvariant().Contains(busca.ToLowerInvariant())
                || s.Unidade.ToLowerInvariant().Contains(busca.ToLowerInvariant())
                || s.Departamento.ToLowerInvariant().Contains(busca.ToLowerInvariant())
                || s.Telefone.Contains(busca)
                || s.Telefone.Contains(busca)
                || s.Email.ToLowerInvariant().Contains(busca.ToLowerInvariant()));
            }

            return dbSet;
        }

Existe alguma limitação com valores nulos nesse caso?