Hi guys i am trying to deploy mvc application to azure. so far, ive done half of the work. so, main web application with AplicationDbContext is were my Identity2.0 tables are for user and roles and so on. Now, i have DAL class library for model and QuizContext for the rest of the application. I what to use one instance of database for storing these two contexts and as u can see from the server explorer on the left its done on localhost, but when i try to publish it on azure only mvc web project is deployed. Just to be sure ive connected with sql management studio to azure database and it only shows Identity tables. After searching for few days online to find solution i gave up cuz they are all basic stuff.
Can u help me make that happen :D My goal is to deploy web application with class library(s) and 2 DbContexts using one database on azure.
Thank u very much.
link to pictures so u get better understanding of my problem
http://testic1.azurewebsites.net/
there is no error msg. at publish console i just get project published - 1 and thats it.
this is dbcontext from class library
namespace Quiz.DAL
{
public class QuizContext : DbContext
{
public QuizContext() : base("name=DefaultConnection")
{
}
public virtual DbSet<Option> Options { get; set; }
public virtual DbSet<Question> Questions { get; set; }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Test> Tests { get; set; }
}
}
this is dbcontext from mvc web application
namespace Quiz.Models
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
}
this is connection string from mvc web project, DAL class library does not have connection string
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Quiz.mdf;Initial Catalog=Quiz;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
Related
I am trying to follow the ASP.NET Web Forms tutorial, just with a MySQL connection instead of local: ASP.NET Web Forms - Create the Data Access Layer
I already tested that the connection string works, because I made a dummy table in an existing DB and I can see it in the Server Explorer when I run the app.
But according to the tutorial, it was also supposed to create a DB and tables and seed it. But nothing happens.
This is my connection string:
<add name="myProject" connectionString="Data Source=MY_PC_NAME;User Id=testuser; Password=testpassword; Integrated Security=False" providerName="System.Data.SqlClient"/>
This is the ProjectContext file:
namespace myProject.Models
{
public class ProjectContext : DbContext
{
public ProjectContext() : base("base_name")
{
}
public DbSet<Item> Items { get; set; }
public DbSet<Category> Categories{ get; set; }
}
}
And the ProjectDatabaseInitializer:
public class ProjectDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProjectContext>
{
protected override void Seed(ProjectContext context)
{
GetItems().ForEach(i => context.Items.Add(i));
GetCategories().ForEach(c => context.Categories.Add(c));
}
// some seeding lists below
I then added the initializer to the Global.asax.cs:
Database.SetInitializer(new ProjectDatabaseInitializer());
And both Items and Categories have their corresponding Item and Category models.
But when I run the app, the Server Explorer remains empty.
Note that I modified the original code of the tutorial a bit
I have an ASP.NET MVC application EducationalCenter with the following structure of projects:
DbContext file is EducationalCenterContext.cs in the Data project and looks as follows:
public sealed class EducationalCenterContext: DbContext
{
public DbSet<Student> Students { get; set; }
public EducationalCenterContext( DbContextOptions<EducationalCenterContext> options)
: base(options)
{
Database.EnsureCreated();
}
}
And in Startup.cs file, the dbContext configured as follows in ConfigureService():
services.AddDbContext<EducationalCenterContext>
(options => options.UseSqlServer("Server=localhost;Database=EducationalCenterDb;Trusted_Connection=True;MultipleActiveResultSets=true"));
This is my working version to which I came by fixing errors when try to add-migration. However it seems awful to me that my web app has project reference to the Data project.
What was my first idea:
In appsettings.json I created this section :
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=EducationalCenterDb;Trusted_Connection=True;MultipleActiveResultSets=true"
}
Then I created AppSettings class in the Common project:
public class AppSettings
{
public string ConnectionString { get; set; }
}
Then I try to pass ConnectionString in DAL via DI:
services.Configure<AppSettings>(Configuration.GetSection("ConnectionStrings"));
And created EducationalDbContext.cs:
public sealed class EducationalCenterContext: DbContext
{
private readonly string _connectionString;
public DbSet<Student> Students { get; set; }
public EducationalCenterContext( IOptions<AppSettings>, DbContextOptions<EducationalCenterContext> options)
: base(options)
{
_connectionString = app.Value.ConnectionString;
Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(_connectionString);
}
}
But when I try to add-migration via PM Console, I ran into this error:
Could not load assembly 'EducationalCenter.Data'. Ensure it is referenced by the startup project 'EducationalCenter'
Then I added project reference and ran into the next error:
Unable to create an object of type 'EducationalCenterContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
Then I added services.AddDbContext<> in Startup.cs and came to the working version which I mentioned above.
So...
Is it normal that my web app has reference to the data access project?
Is it possible to configure EF in the Data project and ensure normal separation between DAL, BLL and web app?
Putting the context and configuration in a separate project is fine.
You got the first error because "Education Center" was set as start up project but did not have reference to data project.
The second error is because the migration builder needs some connection information in the data project to resolve the connection (to compare EF state and database state) to determine what changes are needed.
First add reference in your data project to:
Microsoft.EntityFrameworkCore.Design
Then add a context factory in your data project that migration console command will discover:
internal class MyContextFactory : IDesignTimeDbContextFactory<MyContext>
{
public MyContext CreateDbContext(string[] args)
{
var dbContextBuilder = new DbContextOptionsBuilder<MyContext>();
var connString = "myconnection string";
dbContextBuilder.UseSqlServer(connString);
return new MyContext(dbContextBuilder.Options);
}
}
Question: How do I specify the Entity Framework connection string within a .NET API?
I am accustomed to creating a DAL class and specifying the base connection string like I did here.
public class LocalContext : DbContext
{
public LocalContext() : base("LocalDBContext")
{
}
public DbSet<Weapons> Weapons { get; set;
}
Which in turn grabs the LocalDBContext connection string from the web.config or appsettings.json.
"ConnectionStrings": {
"LocalDBContext": "Server=.;Database=Weapons;Trusted_Connection=True;"
},
This is what I have done in the past in various web apps but not sure if I have to do something different with an API?
I would expect it to call and save into "Weapons" at "Server=." however it instead created a new Database called "LocalDBContext" at the connection of "(localdb)\mssqllocaldb". Any tips would be greatly appreciated!
In EF core you don't need to send a connection to the base class with the constructor, just follow this approach:
public partial class LocalContext : DbContext
{
public LocalContext ()
{
}
public LocalContext(DbContextOptions<LocalContext> options) :
base(options)
{
}
public virtual DbSet<Weapon> Weapons { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
//warning You can move this code to protect potentially sensitive
information
//in connection string.
optionsBuilder.UseSqlServer("Data Source= .;Initial
Catalog=Weapons;Trusted_Connection=True;");
}
}
}
The given String "LocalDBContext" is interpreted as Connectionstring, see official Documentation on DbContext(String).
Do something like:
public class LocalContext : DbContext
{
public LocalContext (DbContextOptions<LocalContext> options)
: base(options)
{
}
....
I have some questions below:
Questions:
Did you add Entity data model in your API solution?
If yes, didn't you save connection string in config file while adding EDM?
While adding EDMX in solution, model window asks to connect the database. Once EDM connects with database, it asks to save connection string in configuration file. You can add tables, functions, SPs, views. This way EDM connects with actual database rather picking different database.
I've seen some of the answers in here, but nothing helped resolving the problem.
I'm following Microsoft ITAcademy tutorial on MVC Jumpstart and they teach by an example that uses EF Code-First approach.
When I'm running the application, I'm getting an error:
CREATE DATABASE permission denied in database 'master'
This is my connection string:
<add name="DefaultConnection"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-Conference-20150930151714;Integrated Security=true"
providerName="System.Data.SqlClient" />`
I do not post all the code in here, since it is a work through Microsoft tutorial line by line.
It fails when I call one of the controller that is supposed to have data retrieved from the database:
public ActionResult Index()
{
return View(db.Speakers.ToList());//fails here with described exception
}
This is how Database is initialized in Global.asax.cs:
using System.Data.Entity;
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
Database.SetInitializer<ConferenceContext>(new ConferenceContextInitializer());
//the rest of code....//
}
}
This is ConferenceContext class:
using System.Data.Entity;
public class ConferenceContext : DbContext
{
//public ConferenceContext() : base("name = DefaultConnection") { }
public DbSet<Session> Sessions { get; set; }
public DbSet<Speaker> Speakers { get; set; }
}
This is a piece of code for adding dummy data to Database:
public class ConferenceContextInitializer : DropCreateDatabaseAlways<ConferenceContext>
{
protected override void Seed(ConferenceContext context)
{
context.Sessions.Add(
new Session()
{
Title = "I want Spaghetti",
Abstract = "The life and times of spaghetti lover",
Speaker = context.Speakers.Add(
new Speaker()
{
Name = "John Doe",
EmailAddress = "john.doe#test.com"
})
});
context.SaveChanges();
}
}
Can you explain me where the database is supposed to be created?
Should I have special permissions on my SQL Server for that or it is just enough to create a database in App_Data folder?
Will I be able to do create Database at all on my work PC?
You need to give your account a global server permission to create database on the server.
I want to have ASP.NET MVC website that would have some frontend for looking into, adding and other things with data. And then I want to have Web Api for getting data for mobile devices and so. I want to use code first from EF (and I am using Ninject). I create classes for hotel and others. I created HotelManagerContext and database is created and looks good. I am adding data by HomeController and by Repository for this. When I looked at database in Visual Studio data are there. But when I tried to use my HotelsController for Api datacontext is empty. What's wrong? What I forget to set? Something with connection string or what?
This is my ApiController:
public class HotelsController : ApiController
{
private IHotelRepository _hotelRepo { get; set; }
public HotelsController(IHotelRepository repo)
{
_hotelRepo = repo;
}
// GET api/Hotels
public IEnumerable<Hotel> GetHotels()
{
return _hotelRepo.GetAll();
}
// GET api/Hotels/5
public Hotel Gethotel(int id)
{
return _hotelRepo.Get(id);
}
}
This is part of my controller for frontend:
public class HomeController : Controller
{
private IHotelRepository _hotelRepo { get; set; }
public HomeController(IHotelRepository repo)
{
_hotelRepo = repo;
}
public ActionResult Index()
{
return View();
}
// next methods, for adding data and so
}
This is my repository:
public class HotelRepository : IHotelRepository
{
private HotelManagerContext db { get; set; }
public HotelRepository()
:this (new HotelManagerContext())
{
}
public HotelRepository(HotelManagerContext hotelManagerContext)
{
// TODO: Complete member initialization
this.db = hotelManagerContext;
}
public Models.Hotel Get(int id)
{
return db.hotels.SingleOrDefault(h => h.hotId == id);
}
public IQueryable<Models.Hotel> GetAll()
{
return db.hotels;
}
public Hotel Add(Hotel hotel)
{
db.hotels.Add(hotel);
db.SaveChanges();
return hotel;
}
}
This is my HotelManagerContext:
public class HotelManagerContext : DbContext
{
public HotelManagerContext() : base("name=HotelManagerContext")
{
}
public DbSet<Hotel> hotels { get; set; }
}
Edit:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IHotelRepository>().To<HotelRepository>();
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
}
Edit2:
Here is my connection string:
<add name="HotelManagerContext" connectionString="Data Source=(localdb)\v11.0; Initial Catalog=HotelManagerContext-20121219191411; Integrated Security=True; MultipleActiveResultSets=True; AttachDbFilename=|DataDirectory|HotelManagerContext-20121219191411.mdf" providerName="System.Data.SqlClient" />
And I just found that even in HomeController I have empty datacontext. So when I check content of database in Server Explorer there are data which I added (in HomeController). But everytime when I have request page (web api or frontend) datacontext is empty and I can add items there are counting from zero but in database there are already next but can't get it. It's really weird.
What does your connection string look like? "name=HotelManagerContext" seems incomplete. I think you would want to also explicitly specify providerName="System.Data.EntityClient" at the very least (see here). In any case, it is common practice to put the connection string in the Web.Config file and assign the name there (i.e. name="HotelMamangerContext") then, under normal circumstances, EF will just discover the connection string by convention as long as the name of your DbContext class matches the name of the connection string in Web.Config (otherwise you can still specify it explicitly in the constructor).
On a different note (I don't think this should be related to you current problem), you could consider injecting you DbContext as well. Then you could drop the parameter-less constructor on your repository class unless you need to keep it around for another reason such as unit testing. Also, if you are using Ninject.Web.Common, you may want to consider scoping the instances to the request level (see InRequestScope).
...
kernel.Bind<HotelMamangerContext>().ToSelf().InRequestScope();
kernel.Bind<IHotelRepository>().To<HotelRepository>().InRequestScope();
...
I can't find solution for this so I create new project and I did everything like in the question. I have same classes, copy and paste code frome question. I can't find any important difference but second time it's working.
I know this isn't exactly solution but in this case I could start my project from begging so I tried it and it really helps. Just don't know where is problem.