0

I try to call a Get Action from my Controller with the specific queries:

[HttpGet]
        public async Task<IActionResult> NiceFormField(int id)
        {

            var form = await _db.Forms.Include(f => f.Ranks)
                .ThenInclude(f => f.Fields)
                .ThenInclude(f => f.Types)
                .Include(f => f.Ranks)
                .ThenInclude(f => f.Fields.MultipleQuestions)
                .AsSingleQuery().TagWith("FormQuery")
                .FirstOrDefaultAsync(f => f.FormId == id);
            var ranks = form.Ranks.OrderBy(x => x.FieldOrder).ToList();

            var count = 1;
            foreach (var i in ranks)
            {
                i.FieldOrder = count;
                count++;

            }

            form.Ranks = ranks;
            return View(form);
        }

When the view tries to Render I get the following error System.NullReferenceException: 'Object reference not set to an instance of an object.' form was null. The weird part is when I inserted a breakpoint on the Action, all the info and the query were correct without null values. After a couple of Continue on the Visual Studio the View renders successfully and the error disappears. I thought it may be a routing issue but other Views with id references and Action calls with queries have no error at all. There are the codes for reference to help you find the issue.
NiceFormField.cshtml

@model Form.Models.FormT

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

<h1>NiceFormField</h1>

<h4>ΟΝΟΜΑ:@Model.FormName ID:@Model.FormId</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="NiceFormField">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="FormId" />
            <div class="form-group">
                <label asp-for="FormName" class="control-label"></label>
                <input asp-for="FormName" class="form-control" />
                <span asp-validation-for="FormName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="AdminName" class="control-label"></label>
                <input asp-for="AdminName" class="form-control" />
                <span asp-validation-for="AdminName" class="text-danger"></span>
            </div>


            <table class="table">
                <thead>
                    <tr>
                        <th scope="col">#</th>
                        <th scope="col">FieldName</th>
                        <th scope="col">FieldToComplete</th>
                        <th scope="col">
                            <div>
                                <a asp-action="AddFieldToForm" asp-route-id="@Model.FormId">+</a>
                            </div>
                        </th>

                    </tr>
                </thead>

                    <partial name="_FieldsParcialView" model="Model" />
            </table>

            <div class="form-group">
                <a asp-action="AdminForm" >Back To Forms</a>
            </div>

        </form>
    </div>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

FormT Model

namespace Form.Models
{
    public class FormT
    {
        [Key]
        public int FormId { get; set; }
        [Required]
        public string FormName { get; set; }
        [Required]
        public string AdminName { get; set; }
        public ICollection<Rank> Ranks { get; set; }
        public ICollection<FormAnswer> Answers { get; set; }
    }
}

Rank Model

namespace Form.Models
{
    public class Rank
    {
        [Key]
        public int RankId { get; set; }
        [ForeignKey("Forms")]
        public int FormId { get; set; }
        [ForeignKey("Fields")]
        public int FieldId { get; set; }
        public int FieldOrder { get; set; }
        public FormT Forms { get; set; }
        public Field Fields { get; set; }
    }
}

FormAnswer Model

namespace Form.Models.Forms
{
    public class FormAnswer
    {
        [Key]
        public int FormAnswerId { get; set; }
        [ForeignKey("Forms")]
        public int FormId { get; set; }
        public FormT Forms { get; set; }

        public ICollection<Answer> Answers { get; set; }
        public FormAnswer()
        {
            Answers = new List<Answer>();
        }
    }
}

FieldType Model

namespace Form.Models
{
    public class FieldType
    {
        [Key]
        public int FieldTypeId { get; set; }
        [Required]
        public string Type { get; set; }
        public ICollection<Field> Fields { get; set; }
    }
}

Field Model

namespace Form.Models
{
    public class Field
    {
        [Key]
        public int FieldId { get; set; }
        [Required]
        public string FieldName { get; set; }
        [ForeignKey("Types")]
        public int FieldTypeId { get; set; }
        public FieldType Types { get; set; }
        public ICollection<Rank> Ranks { get; set; }
        public ICollection<MultipleQuestion> MultipleQuestions { get; set;}
    }
}

Answer Model

namespace Form.Models.Forms
{
    public class Answer
    {
        public int FormAnswerId { get; set; }
        public int RankId { get; set; }
        public string AnswerValue { get; set; }
        public FormAnswer formAnswer { get; set; }
    }
}

MultipleQuestion

namespace Form.Models.Forms
{
    public class MultipleQuestion
    {
        [Key]
        public int QuestionId { get; set; }
        [ForeignKey("Fields")]
        public int FieldId { get; set; }
        public string QuestionValue { get; set; }

        public Field Fields;
    }
}

Startup.cs

using Blazored.LocalStorage;
using Form.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Form
{
    public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
            Environment = env;
        }

        public IConfiguration Configuration { get; }
        public IWebHostEnvironment Environment { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            if (Environment.IsDevelopment())
            {
                services.AddDbContext<ApplicationDbContext>(
                   options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
                   );
                services.AddControllersWithViews()
                    .AddRazorRuntimeCompilation().AddNewtonsoftJson(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore) ;
            }
            else
            {
                services.AddDbContext<ApplicationDbContext>(
                options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
                );
                services.AddControllersWithViews();

            }
            services.AddRazorPages();
            services.AddHttpClient();
            services.AddServerSideBlazor();
            services.AddBlazoredLocalStorage();




            services.AddControllers()
                    .AddNewtonsoftJson(options =>
                    {
                        options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                    });
            services.AddCors(options =>
            {
                options.AddDefaultPolicy(
                    builder =>
                    {
                        builder.WithOrigins("http://example.com",
                                            "https://localhost:44349/",
                                            "https://localhost:44349/UserAllFormsComponets");
                    });
            });

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseWebAssemblyDebugging();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseBlazorFrameworkFiles();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseCors();
            app.UseAuthorization();


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
                endpoints.MapControllers();
                endpoints.MapFallbackToFile("index.html");

            });
        }
    }
}

StackTrace Message at Form.Controllers.FormsController.d__18.MoveNext()

  • Could you include the StackTrace too? – phuzi Jul 28 '21 at 09:22
  • @phuzi StackTrace included. Don't know if it will help. – Konstantinos Manolis Jul 28 '21 at 09:34
  • The error is descriptive enough. `FirstOrDefaultAsync(f => f.FormId == id)` gives returns nothing i.e. you have no such record in DB – abdusco Jul 28 '21 at 09:35
  • @abdusco The page renders fine after 2 Continue on Visual Studio with all the info I need. If i dont use debug mode everything seems perfect from the Client perspective. Server side has that issue. As I mentioned above, with breakpoint on that line I get every info from the DB without any problem. But when the Model is returned to view seems like the action is called again without the ID so everything is null afterwards thus the error. – Konstantinos Manolis Jul 28 '21 at 09:47
  • Hmm. Can you see a second request in the browser console? – abdusco Jul 28 '21 at 09:48
  • 1
    @abdusco Well. There were some errors on the Client Console that I never thought that will cause prolbem. It was some tags with css reference that couldnt be imported that caused the problem. I deleted them so the problem was fixed. Thank you for the info on the Browser Console, it was the last thing that would came to my mind to fix the problem. – Konstantinos Manolis Jul 28 '21 at 10:02

0 Answers0