System.Data.SqlTypes.SqlNullValueException after I migrated to net5.0 from netcore 3.1 - asp.net-core

I'm getting this error on one of my fetch services
System.Data.SqlTypes.SqlNullValueException
HResult=0x80131931
Message=Data is Null. This method or property cannot be called on Null
values. Source=Microsoft.Data.SqlClient StackTrace: at
Microsoft.Data.SqlClient.SqlBuffer.get_Int32() at
Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.Enumerator.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at
Infrastructure.Data.Repository.Base.EfRepository1.List(ISpecification1
spec) in C:\mydir\master\src\DataTier\SMYLS.Data.Respository\Repository\Base\EfRepository.cs:line
88 at
ApplicationCore.Services.Items.ItemService.SearchItems(ItemSearchDataModel
searchModel) in C:\mydir\master\src\ServiceTier\SMYLS.Services\Items\ItemService.cs:line 202 at
Web.Controllers.Api.InvoiceController.GetItemList(ItemSearchDataModel
searchModel) in C:\mydir\master\src\Web\Controllers\Api\InvoiceController.cs:line 322 at
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper
mapper, ObjectMethodExecutor executor, Object controller, Object[]
arguments) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State&
next, Scope& scope, Object& state, Boolean& isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
This exception was originally thrown at this call stack:
[External Code]
Infrastructure.Data.Repository.Base.EfRepository.List(ApplicationCore.Interfaces.Repository.ISpecification)
in EfRepository.cs
ApplicationCore.Services.Items.ItemService.SearchItems(ApplicationCore.DTOs.Items.ItemSearchDataModel)
in ItemService.cs
Web.Controllers.Api.InvoiceController.GetItemList(ApplicationCore.DTOs.Items.ItemSearchDataModel)
in InvoiceController.cs
[External Code]
This happened after I migrated to net5.0. If I run my netcore3.1, there's no problem at all.
I've researched this error and mostly found errors that were caused when your model is expecting a required property but the database returns a null value. I checked my models but they seem fine (they work on 3.1 without any issue)
these are my model properties
public string Name { get; set; }
public string Description { get; set; }
public decimal Cost { get; set; }
public bool Active { get; set; }
public DateTime UpdatedDateUtc { get; set; }
public int UpdatedBy { get; set; }
public int ClinicId { get; set; }
public int? ServiceGroupId {get;set;}
public string ShortCode { get; set; }
public int? IndustryCodeId { get; set; }
public bool Subscription { get; set; }
public bool BlockBill { get; set; }
public decimal? DiscountPercentage { get; set; }
#nullable enable
public string? SubscriptionType { get; set; }
public virtual Clinic Clinic { get; set; }
public virtual SiteUser UpdatedByNavigation { get; set; }
public virtual ServiceGroup ServiceGroup { get; set; }
public virtual IndustryCode IndustryCode { get; set; }
public virtual ICollection<InvoiceItem> InvoiceItem { get; set; }
public virtual ICollection<DoctorPricing> DoctorPricing { get; set; }
public virtual ICollection<DoctorPricingHistory> DoctorPricingHistory { get; set; }
And these are my sample data from db
Still can't figure out why this is not working in net5.0

On quick glance, I’d suspect the ServiceGroup property, which has a return type of ServiceGroup, but corresponds to a nullable ServiceGroupId column in the database. I’d expect that the return type of the property would need to be ServiceGroup? to allow for nulls.
I’m not certain why that wasn’t throwing an exception in ASP.NET Core 3.x. My suspicion is that ASP.NET Core 5.x does a better job of enforcing nullability of reference types at runtime, thus raising awareness of a long-standing discrepancy in the data model.

Related

The new ASP.NET Core 3.0 Json serializer is leaving out data

I'm porting a web application to ASP.NET Core 3, and after a bit of a battle, I'm almost at the finish line. Everything seems to work, but all of a sudden my JSON data returned from the api is missing some levels.
It seems the options.JsonSerializerOptions.MaxDepth is default at 64 levels, so it can be that. Some other places where an option can be playing tricks on me?
This is the code (and a quickview of the value):
And this is the JSON I get in the browser:
So the ParticipantGroups property/collection is completely missing in the generated output.
Any ideas where this happens?
EDIT:
I've added a repo on Github that showcases the issue. Standard ASP.NET Core 3.0 solution, created from the template, with a change to the result returned from the Weatherforecast controller:
https://github.com/steentottrup/systemtextjsonissue
For now I've gone back to using Newtonsoft.Json, with the Microsoft.AspNetCore.Mvc.NewtonsoftJson package. Then when I have some time, I'll try finding out what the solution is, without Newtonsoft.Json.
The problem seems to be an error in the new version 3.0. At least it seems like an error to me.
It seems System.Text.Json will convert the class mentioned in the hierarchy, not the actual class. So if you are using an abstract class in the hierarchy, you're in trouble. The second I removed the base class, and used the actual class I'm returning, the problem goes away it seems.
So this doesn't work:
public class SurveyReportResult {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
public IEnumerable<OrganisationalUnit> OrganisationalUnits { get; set; }
}
public abstract class OrganisationalUnit {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
}
public class OrganisationalUnitWithParticipantGroups : OrganisationalUnit {
public IEnumerable<ParticipantGroup> ParticipantGroups { get; set; }
}
public class ParticipantGroup {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
}
This will only return the properties of the OrganisationalUnit class, not the additional property of the OrganisationalUnitWithParticipantGroups.
This works:
public class SurveyReportResult {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
public IEnumerable<OrganisationalUnitWithParticipantGroups> OrganisationalUnits { get; set; }
}
public class OrganisationalUnitWithParticipantGroups /*: OrganisationalUnit*/ {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
public IEnumerable<ParticipantGroup> ParticipantGroups { get; set; }
}
public class ParticipantGroup {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
}

Automapper and EF Navigation Properties

With ASP.NET MVC Core and Entity Framework Core I'm trying to create a simple website.
I've defined my Model:
public class Club
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<Team> Teams { get; set; }
}
public class Team
{
[Key]
public int Id { get; set; }
public int ClubId { get; set; }
[MaxLength(32)]
public string Name { get; set; }
public virtual Club Club { get; set; }
}
As well as the corresponding View Models:
public class ClubViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<TeamViewModel> Teams { get; set; }
}
public class TeamViewModel
{
public int Id { get; set; }
public int ClubId { get; set; }
public string Name { get; set; }
public virtual ClubViewModel Club { get; set; }
}
I've defined an Automapper Profile with the corresponding mappers:
CreateMap<Club, ClubViewModel>();
CreateMap<ClubViewModel, Club>();
CreateMap<Team, TeamViewModel>();
CreateMap<TeamViewModel, Team>();
I try to load a Club entity, with the navigation property Teams included (_context.Club.Include(c => c.Teams).ToList()). This works as expected, it returns a Club with a list of Teams. But when I try to map this instance to a ClubViewModel, I get an 502.3 error and my debug session is ended immediately.
It seems like I am missing something trivial, but I simply do not see it. There's no information in the Windows Event Log and I can't find any usefull information in the IIS Express logging (%userprofile%\documents\IISExpress)
What is causing the crash?
You can't perform this mapping because it is circular. You'll have to remove this line
public virtual ClubViewModel Club { get; set; }
from your TeamViewModel and the mapping should work as expected.

I am using complex type as datamember of a datacontract

I am using complex type as datamember of a datacontract. But the service is throwing an exception if i set [DataMember] to the complextype. What might be the reason. KIndly suggest. Below is the code snippet
[DataContract]
public class GetDetailsFromCardNumberResponseBody
{
public GetDetailsFromCardNumberResponseBody()
{
}
public GetDetailsFromCardNumberResponseBody
(PatronAccountCardValidation GetDetailsFromCardNumberResult)
{
this.GetDetailsFromCardNumberResult = GetDetailsFromCardNumberResult;
}
[DataMember]
public PatronAccountCardValidation GetDetailsFromCardNumberResult { get; set; }
}
[DataContract(Name="PatronAccountCardValidation")]
public class PatronAccountCardValidation
{
[DataMember]
public Patron Patron { get; set; }
[DataMember]
public Card Card { get; set; }
[DataMember]
public string BonusDollarLocal { get; set; }
[DataMember]
public string BonusDollarRemote { get; set; }
[DataMember]
public bool Valid { get; set; }
[DataMember]
public string MessageText { get; set; }
}
Check the parameter PatronAccountCardValidation.
Check property Card. It is causing an issue. Please help.
Error received:
An unhandled exception of type
'System.ServiceModel.CommunicationException' occurred in mscorlib.dll
Additional information: An error occurred while receiving the HTTP
response to localhost:9090/DoorAccessAndVendingMachineService. This
could be due to the service endpoint binding not using the HTTP
protocol. This could also be due to an HTTP request context being
aborted by the server (possibly due to the service shutting down). See
server logs for more details
Have you consider to apply Data Contract Know types? It allows you to specify, in advance, the types that should be included for consideration during deserialization. And by default during deserialization, an uninitialized object is first created, without calling any constructors on the type. Then all data members are deserialized. See more details here.
[DataContract]
[KnownType(typeof(PatronAccountCardValidation))]
public class GetDetailsFromCardNumberResponseBody
{
public GetDetailsFromCardNumberResponseBody()
{
}
public GetDetailsFromCardNumberResponseBody
(PatronAccountCardValidation GetDetailsFromCardNumberResult)
{
this.GetDetailsFromCardNumberResult = GetDetailsFromCardNumberResult;
}
[DataMember]
public PatronAccountCardValidation GetDetailsFromCardNumberResult { get; set; }
}
[KnownType(typeof(Card))]
[KnownType(typeof(Patron))]
[DataContract(Name="PatronAccountCardValidation")]
public class PatronAccountCardValidation
{
[DataMember]
public Patron Patron { get; set; }
[DataMember]
public Card Card { get; set; }
[DataMember]
public string BonusDollarLocal { get; set; }
[DataMember]
public string BonusDollarRemote { get; set; }
[DataMember]
public bool Valid { get; set; }
[DataMember]
public string MessageText { get; set; }
}

ASP.NET MVC/EF Code First error: Unable to retrieve metadata for model

I'm trying to create a controller in MVC4 and I'm getting an error I don't understand (I'm new to MVC). It says "Unable to retrieve metadata for 'CIT.ViewModels.DashboardViewModel'..." and then gives 2 possible problems. One is that the DashboardViewModel has no key defined. The other is that EntitySet 'DashboardViewModels' has no key defined.
I defined a key for DashboardViewModel, but that didn't solve the problem. Here is my DashboardViewModel;
public class DashboardViewModel
{
public DashboardViewModel() { }
[Key]
public int Id { get; set; }
public Hardware Hardware { get; set; }
public Software Software { get; set; }
public HardwareType HardwareType { get; set; }
public Manufacturer Manufacturer { get; set; }
public SoftwarePublisher SoftwarePublisher { get; set; }
}
As you can see it is composed of classes. I did this so I could have multiple classes accessible from the same view. I didn't think it needed a key, but I added one and that didn't fix the problem. The other error sounded like it was looking for a DbSet for DashboardViewModels. As I understand it, your DbSets are your tables. I don't want or need a DashboardViewModels table. I'm only doing that so I can have multiple tables/classes accessible in my view. That's working fine up to this point.
When I am trying to create the controller, I am using the DashboardViewModel as as my model and Context as my context. Here is my context:
public class Context : DbContext
{
public DbSet<Software> Softwares { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<SoftwarePublisher> SoftwarePublishers { get; set; }
public DbSet<SoftwareType> SoftwareTypes { get; set; }
public DbSet<Hardware> Hardwares { get; set; }
public DbSet<Manufacturer> Manufacturers { get; set; }
public DbSet<HardwareType> HardwareTypes { get; set; }
}
How do I address these errors?

Fluent NHibernate Mapping Non Required Object using Automapping

I have a composite object set up Project->Appraisal, My appraisal object has a ApprovedMentor object which is not required but when i go to save project Nhib throws and error to say that ApprovedUser has not been set. but its not set because its not a required field. How do i set up this using fluent auto mapping, is it possible?
public class MentoringProject : BaseEntity
{
public MentoringProject()
{
Appraisal = new Appraisal();
}
[NotNullNotEmpty]
[Length(Min=25, Max=1000)]
public virtual string Description { get; set; }
[Length(Min=25, Max=1000)]
public virtual string SupportRequired { get; set; }
[NotNullNotEmpty]
public virtual System.DateTime? DateSubmitted { get; set; }
[NotNullNotEmpty]
public virtual System.DateTime? ClosingDate { get; set; }
[NotNullNotEmpty]
[Size(Min=1)]
public virtual short Duration { get; set; }
[NotNullNotEmpty]
public virtual string Skills { get; set; }
public virtual Appraisal Appraisal { get; set; }
}
public class Appraisal : BaseEntity
{
public Appraisal()
{
ShortlistedMentors = new List<User>();
ApprovedMentor = new User();
College = new RefData();
}
#region Primitive Properties
public virtual bool Decision { get; set; }
public virtual System.DateTime? ApprovedDate { get; set; }
public virtual System.DateTime? AcceptedDate { get; set; }
public virtual System.DateTime? CompletionTargetDate { get; set; }
public virtual string RejectionReason { get; set; }
#endregion
#region Navigation Properties
public virtual IList<User> ShortlistedMentors { get; set; }
public virtual User ApprovedMentor { get; set; }
public virtual RefData College { get; set; }
#endregion
}
It looks to me that you just want to ignore the ShortlistedMentors property which you need to do in your mapping class like this:
map.IgnoreProperty(p => p.ShortlistedMentors);
This answer was posted in this question.
I think i have solved this, when binding the UI to the controller in MVC, MVC creates an empty User object and because that object has required fields set on it using nhib validator and nhib was trying to create a new user object, I got round this by checking if there is a user realtionship to add, if not I set the Appraisal.ApprovedMentor==null