ASP.NET Core Web API Error: Model 1[TContext] violates the Constraint of type 'TContext' - asp.net-core

I have a Solution in Visual Studio 2017 that contains the following Projects:
CredentialManager.API (ASP.NET Core 2.1 Web API project)
CredentialManager.Models (Class Library that contains the Domain Model and Data Context Class)
The Domain Model Class is coded as follows:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace CredentialManager.Models.Entities
{
public class Credential
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long CredentialId { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string Application { get; set; }
}
}
The Data Context Class is as follows:
using System;
using System.Collections.Generic;
using System.Text;
using CredentialManager.Models.Entities;
using Microsoft.EntityFrameworkCore;
namespace CredentialManager.Models.Context
{
public class CredentialManagerContext : DbContext
{
public CredentialManagerContext(DbContextOptions options)
: base(options)
{ }
public DbSet<Credential> Credentials { get; set; }
}
}
The appsettings.json file looks like the following:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"ConnectionStrings": {
"i.": null,
"CredentialManagerDB": "server=.\\SQLEXPRESS;database=CredentialManagerDB;Trusted_Connection=true;"
},
"AllowedHosts": "*"
}
The Startup.CS file looks like this:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDbContext<CredentialManagerContext>(o => o.UseSqlServer(Configuration["ConnectionStrings:CredentialManagerDB"]));
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
I then build the Solution and Added Migrations. But when I run update-database, I get the following error:
GenericArguments[0], 'CredentialManager.Models.Migrations.CredentialManagerContext', on 'Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory`1[TContext]' violates the constraint of type 'TContext'.
Can someone here throw some light on this error ? If I include the classes and data context in the same folder as the API project, then everything works.. But I want these classes to be part of a separate Class Library Project. Any help would be much appreciated.
Thanks.

Update context file to have the following:
public CredentialManagerContext(DbContextOptions<CredentialManagerContext> options)
: base(options)
{ }
As outlined in the documentation:
This requires adding a constructor argument to your DbContext type that accepts :
DbContextOptions<TContext>
This should resolve your issue.

Thank you for all the suggestions. I found a Solution as well. The Startup.cs needs to be informed about the Project that contains the Migrations:
services.AddDbContext<CredManagerContext>(options => options.UseSqlServer(Configuration.GetConnectionString("CredentialManagerDB"), x => x.MigrationsAssembly("CredManager.Models")));
Everything works perfectly after this.

Related

fluent validator in class library not work in asp.net core

when i put fluent validators in asp.net core client side validation project exactly work
but when i put validator in class library not work
My model and validator in class library :
using FluentValidation;
namespace ClassLibrary1
{
public class Person
{
public string Name { get; set; }
public string Family { get; set; }
public int Age { get; set; }
}
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(c => c.Name).NotEmpty().WithMessage("Name Is Empty");
}
}
}
In program.cs file :
services.AddFluentValidationAutoValidation(M =>
{
M.DisableDataAnnotationsValidation = true;
}).AddFluentValidationClientsideAdapters()
.AddValidatorsFromAssemblyContaining<PersonValidator>();
I can't reproduce the issue, and it works in my side, I will show my test steps.
Steps
my project structure.
The person.cs code same as yours
The program.cs code same as yours
My test method in Controller.
[HttpPost]
[Route("Test")]
public IActionResult Test([FromBody]Person model)
{
if (!ModelState.IsValid) //<----Validate here
{
return new BadRequestObjectResult(ModelState);
}
return Ok();
//Other Code..
}
Test result and it works.
I found the solution.
When the class library is nullable, the client-side validation in ASP.NET Core does not work.
Solution:
Remove <Nullable>enable</Nullable> from the *.csproj
Define nullable property:
public string? name{get;set}

Migration Issue AspNetCore API

I am working on a project in which I am using the code-first approach to add migration of my existing entities. I am facing the following related issue shown in the image.
Here is my dbContext class
public class LicenseDbContext: IdentityDbContext<LicenseUser, LicenseUserRole, long>
{
public LicenseDbContext(
DbContextOptions<LicenseDbContext> options
) : base(options)
{
}
}
Here is are License User and LicenseUserRole classes
public class LicenseUser : IdentityUser<long>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public ApplicationRoleEnum UserRole { get; set; }
}
public class LicenseUserRole : IdentityRole<long>
{
public LicenseUserRole() : base()
{
}
public LicenseUserRole(string roleName) : base(roleName)
{
}
}
I am using EF Core version 5.0.9. It always says installation of both EF6 and EFCore though I have installed only Core.
An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the application service provider. Error: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type 'TRole'.
For this issue, I can reproduce it when I register wrong IdentityRole.
Be sure register your service like below:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<LicenseDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<LicenseUser, LicenseUserRole>(options => options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<LicenseDbContext>();
//other services...
}

Does OData actually work in AspNetCore on Linux?

I work in an environment where all new work is done in AspNetCore, one of the primary reasons being so we can run it on Linux servers. We have an API to access one of our databases that I've been asked to add OData to. No problem.
The Problem
I've got a lovely example working in a test project and I'm moving it over to the real API in a branch of the code annnnnnd.....what's that? It's a reference to Microsoft.AspNet.
My test project is .NetCore 2.1, and the only NuGet packages installed are:
Microsoft.AspNetCore.App v2.1.1
Microsoft.AspNetCore.OData v7.0.1 (tried v7.1.0 too)
Microsoft.AspNetCore.Razor.Design v2.1.2
Microsoft.NETCore.App v2.1.0
This (truncated) code works great on my Windows development machine, but I foresee problems when we try to build it for Linux deployment.
Startup.cs - Notice the first 2 usings
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OData.Edm;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ODataTest.Models;
namespace ODataTest
{
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
...
services.AddOData();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseMvc(b =>
{
b.Filter().Expand();
b.MapODataServiceRoute("odata", "odata", GetEdmModel());
b.EnableDependencyInjection();
});
}
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<ThingDto>(nameof(ThingDto));
return builder.GetEdmModel();
}
}
}
ThingController.cs - Notice using #3
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.OData;
using Microsoft.AspNetCore.Mvc;
using ODataTest.Models;
namespace ODataTest.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ODataController
{
private readonly Db _db;
public ValuesController(Db db)
{
this._db = db;
}
[HttpGet]
[EnableQuery]
public ActionResult<IEnumerable<ProductPricePointMarkdownDto>> Index()
{
var things =
from thing in _db.Things
select new ThingDto
{
ThingID = thing.ID,
StyleID = thing.StyleID,
ColourID = thing.ColourID
};
return Ok(things);
}
}
}
ThingDto.cs - Notice the last using
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.OData.Query;
namespace ODataTest.Models
{
[Filter("ColourID", Disabled = true)]
[Filter]
public class ThingDto
{
[Key]
public int ThingID { get; set; }
public int StyleID { get; set; }
public int ColourID { get; set; }
}
}
Can anyone steer me away from my current thinking that OData "works with Core" is marketing, and in reality it doesn't?
So the answer is "Yes, it does work". I have not tracked down whether it's a bad namespace, or actually referring to .NET Standard. The motivation to find out went once I proved this ran on a Linux docker container.

Can I use startup.cs to load AppSettings

Can I write code in startup.cs...Configuration method to call my DataAccess layer and/or some other class to assign data to my static class after reading the configurations either from DB or from AppSettings from web.config file to read all my app configurations during the startup. I've tried to access my Static Class in startup.cs by adding reference to the library where my class resided, but I'm not able to access it in my asp.net MVC4 app.
namespace CAS.Common
{
public static class CommonConfiguration
{
public static string CDSRestClient { get; set; }
public static string ClientIdValue { get; set; }
public static string ClientSecretValue { get; set; }
}
}
Code from Startup.cs
using System.Configuration;
using CAS.Common;
namespace myWebApp
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
//This is the intended code, which I'm not able to do as I'm not able to access my static class here.
CommonConfiguration.CDSRestClient = ConfigurationSettings.AppSettings["CDSRestClient"].ToString().Trim();
CommonConfiguration.ClientIdValue = ConfigurationSettings.AppSettings["clientIdValue"].ToString().Trim();
CommonConfiguration.ClientSecretValue = ConfigurationSettings.AppSettings["clientSecretValue"].ToString().Trim();
}
}
}
Can anyone tell me what am I doing wrong here.

How to add web API to an existing MVC Hottowel project

I have one Hottowel project created using it's template from Visual Studio. I want to add the Web API feature in that project. I have created a Web Api controller to the controller folder and tries to access like "http://localhost:53397/api/Values" But I get an error saying The resource cannot be found error.
My controller code looks like below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace MvcApplication8.Controllers
{
public class ValuesController : ApiController
{
// GET api/<controller>
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<controller>/5
public string Get(int id)
{
return "value";
}
// POST api/<controller>
public void Post([FromBody]string value)
{
}
// PUT api/<controller>/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/<controller>/5
public void Delete(int id)
{
}
}
}
I have the cs file in APP_start folder called BreezeWebApiConfig.cs which contains the logic to map the route like below.
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "BreezeApi",
routeTemplate: "api/{controller}/{action}"
);
Let me know If I am missing any configuration setting for Web APi.
Try to decorate your ApiController like bellow :
[BreezeController]
public class NorthwindIBModelController : System.Web.Http.ApiController {
readonly EFContextProvider<NorthwindIBContext> ContextProvider =
new EFContextProvider<NorthwindIBContext>();
[HttpGet]
public String Metadata() {
return ContextProvider.Metadata();
}
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle) {
return ContextProvider.SaveChanges(saveBundle);
}
[HttpGet]
public IQueryable<Customer> Customers() {
return ContextProvider.Context.Customers;
}
For more information have a look to breeze documentation here.
Its seems like you are making a wrong Url Request. Look at your breeze route configuration for WebApi. You need to Pass like that http://localhost:53397/api/Values/Get as breeze is using Controller action based routing.
Hope this will help.