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()