I have created application in mvc3 and I used the default account controller for my users.
I followed instructions from http://www.asp.net/mvc/tutorials/authenticating-users-with-forms-authentication-cs to put all tables (from aspnetdb) in one database.
My trouble is how to set webconfig and connection string corectly?
I set the conn string to my databse but if I try to register Visual studio create aspnetdb and put my user info there.
I am trying to find solution to stop vs creating aspnetdb.
My hosting provider is http://www.inside.hr it is hosting company from Croatia
If your shared hosting environment only allows you to use one database, you can add the ASP.NET Membership database tables to your existing database. Joe Stagner has a walkthrough on how to do that here.
Can you update your question to tell us where you're hosting? That will help.
I'm not sure if I follow you correctly, but did you try something like this:
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
<add name="MyDevArmyDB" connectionString="Data Source=DATASOURCE;Initial Catalog=devarmydb;Persist Security Info=True;User ID=USERID;Password=PASSWORDSTRING"
providerName="System.Data.SqlClient" />
</connectionStrings>
DATASOURCE- replace with the address of your database
USERID- replace with the actual user id
PASSWORDSTRING- replace with the actual password
Accessing the DB is done like this:
public class SqlUserRepository : IUserRepository
{
private DataContext dataContext;
private Table<User> usersTable;
public IQueryable<User> Users { get { return usersTable; } }
public SqlUsersRepository(string databaseName)
{
HttpRequestWrapper request = new HttpRequestWrapper(System.Web.HttpContext.Current.Request);
Configuration config = WebConfigurationManager.OpenWebConfiguration(request.ApplicationPath);
dataContext = new DataContext(config.GetConnetionString(databaseName));
}
}
Note that GetConnectionString is an extension function which supports encryption/decryption of the connection string (if you decide to protect the connection string):
public static class ConfigExtension
{
public static string GetConnetionString(this Configuration config, string databaseName, string provider = "RSAProtectedConfigurationProvider")
{
string sectionName = "connectionStrings";
ConfigurationSection section = config.GetSection(sectionName);
if (section != null && !section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection(provider);
config.Save();
}
return WebConfigurationManager.ConnectionStrings[databaseName].ConnectionString;
}
}
Related
I'm creating a new MVC 3 pilot application using Mvc3 and the MvcScaffolding NuGet, everything runs smoothly until i want to use the database i already have. The application keeps creating a database with the format:
projectname.Models.projectnameContext
I'm stuck in here, my connectionStrings is:
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" />
<add name="EnginesTrackingEntities" connectionString="metadata=res://*/Models.Model1.csdl|res://*/Models.Model1.ssdl|res://*/Models.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=WARCHLAPPY\SQLEXPRESS;initial catalog=[EnginesTracking];integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
In which specifies that my database is EnginesTracking.
Update
I'm following the database first approach from this example.
I have everything working perfectly but when the application starts, it creates a new table instead of using the one i specified.
The only one difference is that there is no databaseEntities in my project, instead there is projectContext for which i cannot do the number 8 step
Update2
I'm kinda given up on this, going to follow codeFirst approach as this is taking to much time for only being a pilot.
This is the Model1.context.cs:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ErrorReportingSystem.Models{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class EnginesTrackingEntities : DbContext
{
public EnginesTrackingEntities()
: base("name=EnginesTrackingEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Engine_Part> Engine_Part { get; set; }
public DbSet<Engines> Engines { get; set; }
public DbSet<Error> Error { get; set; }
public DbSet<Has_error> Has_error { get; set; }
public DbSet<Locations> Locations { get; set; }
public DbSet<Operators> Operators { get; set; }
public DbSet<sysdiagrams> sysdiagrams { get; set; }
}
}
I finally found the problem. I found a similar issue here which finished pointing me in the right direction.
I had to add:
public ErrorReportingSystemContext() : base("name=EnginesTrackingEntities") { }
To the ErrorReportingSystemContext.cs file under /Models folder.
Done!
Seems like you are using Code First Entity Framework. The post will probably get the best exposure in that forum. EnginesTrackingEntities is an EF connect string.
One of the big problems in dealing with code-first is the db drop and re-create with every change to your POCO's.
I strongly prefer database first approach because it is not as hard to deploy (not hard at all) and where you are pointing is clear. The advantage of code first is being able to elegantly style and decorate your POCO's.
I'm not exactly answering your question due to lack of info, but helping direct you. With a little more info on your deployment and Entities, I may be able to help more.
I have trying to find the way to use EFCachingProvider from Tracing and Caching Provider Wrappers for Entity Framework with Entity Framework and DbContext. I use EF 4.x DbContext Generator for c# to generate model classes.
I've already added references to EFProviderWrapperToolkit, EFCachingProvider, EFTracingProvider. I also made changes in my web.config file to :
<connectionStrings>
<add name="MyEntities" connectionString="Server=myServer;Database=MyDB;User ID=User;Password=pass;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" providerName="EFTracingProvider" />
</connectionStrings>
<system.data>
<DbProviderFactories>
<add name="EF Caching Data Provider" invariant="EFCachingProvider" description="Caching Provider Wrapper" type="EFCachingProvider.EFCachingProviderFactory, EFCachingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
<add name="EF Tracing Data Provider" invariant="EFTracingProvider" description="Tracing Provider Wrapper" type="EFTracingProvider.EFTracingProviderFactory, EFTracingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
<add name="EF Generic Provider Wrapper" invariant="EFProviderWrapper" description="Generic Provider Wrapper" type="EFProviderWrapperToolkit.EFProviderWrapperFactory, EFProviderWrapperToolkit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
</DbProviderFactories>
</system.data>
But when app start, it throws an error in DbConnectionWrapper from EFProviderWrapperToolkit
in line:
DbProviderFactory factory = DbProviderFactories.GetFactory(providerInvariantName);
This is class which inherits from DbContext:
public class MyEntities : DbContext
{
public MyEntities()
: base("MyEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Entity<Product>().ToTable("Product");
modelBuilder.Entity<ProductPhoto>().ToTable("ProductPhoto");
base.OnModelCreating(modelBuilder);
}
public DbSet<Product> Product { get; set; }
public DbSet<ProductPhoto> ProductPhoto { get; set; }
}
I've already read post: USING TRACING AND CACHING PROVIDER WRAPPERS WITH CODEFIRST, but it didn't solve my problem.
Does anyone know how to do it ?
We have used the EFCachingProvider with Entity Framework and and Code First. You can see our implementation in our source code for MVCForum on CodePlex.
We found that there were many examples that showed the tracing provider but nothing that showed the caching provider with Code First.
It didn't just work with our code out of the box. We had a problem using DbContext and TransactionScope. In order to make calls that were overridden in the EFCachingProvider wrapper, and thereby redirected to the cache, we needed to use transactions from the connection, rather than TransactionScope. We couldn't get to the connection from our DbContext because it handles the connection itself, so we used the underlying ObjectContext.
private readonly IDbTransaction _transaction;
etc
_objectContext = ((IObjectContextAdapter) _context).ObjectContext;
if (_objectContext.Connection.State != ConnectionState.Open)
{
_objectContext.Connection.Open();
_transaction = _objectContext.Connection.BeginTransaction();
}
The caching provider then intercepts calls appropriately. We use the _transactionobject to issue Commit() or Rollback etc.
You can see the full implementation in our UnitOfWork class.
I'm using a custom IIdentity and IPrincipal in my ASP.NET MVC application via EF 4.3 as expalined here (and follow accepted answer's solution). Also, I have a custom RoleProvider. In local (using IIS Express), it works currectly. But now, when I upload the application on a real host, it seems all users are in "admin" role! e.g. I create a user that is not in role "admin", but it can access to all protected pages (that need "admin" role). e.g. Role.IsUserInRole always returns true. Have you any idea please? Can you help me? Is there any setting that I should to do in IIS?
I explain that solution and it works for me. I don't now, may be you should rollback to the AuthenticateRequest event.If you want to try this way, you have to remove RoleManagerModule completely from your project. Try this and let me know if works or nop:
// in your module:
public void Init(HttpApplication context) {
_application = context;
// rollback this line:
_application.AuthenticateRequest += ApplicationAuthenticateRequest;
}
// and in web.config
<!-- in system.web section: -->
</system.web>
<!-- other stufs -->
<httpModules>
<remove name="RoleManager"/>
</httpModules>
</system.web>
<!-- and in system.webServer section: -->
<system.webServer>
<!-- other stufs -->
<modules runAllManagedModulesForAllRequests="true">
<remove name="RoleManager"/>
</modules>
<system.webServer>
If you want to keep using the default RoleManager, it gets difficult. I tried creating my own RoleManager by deriving from the default, without any luck.
After 2 days trying several things, I ended up creating some extension methods for RolePrincipal:
public static bool IsEmployee(this RolePrincipal principal)
{
if (IsAuthenticated())
return principal.IsInRole("Employee");
return false;
}
public static bool IsAdmin(this RolePrincipal principal)
{
if (IsAuthenticated())
return principal.IsInRole("Admin");
return false;
}
Created a new WebViewPage class:
public abstract class BaseViewPage : WebViewPage
{
public virtual new RolePrincipal User
{
get
{
if (base.User == null)
return null;
return (RolePrincipal)base.User; //Hard casting: If it goes wrong, it better goes wrong here
}
}
}
public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
public virtual new RolePrincipal User
{
get
{
if (base.User == null)
return null;
return (RolePrincipal)base.User; //Hard casting: If it goes wrong, it better goes wrong here
}
}
}
Modified the web.config in the views folder:
<pages pageBaseType="MyCompany.MyProject.BaseViewPage">
And all my Controllers derive from my BaseController:
public abstract class BaseController : Controller
{
protected virtual new RolePrincipal User
{
get { return HttpContext.User as RolePrincipal; }
}
}
Downside is that the methods query my database everytime they get called.
I'm using MVC 4 btw
Hope this helps anyone
I've created a new MVC 3 website using EF 4.1 with DB first approach. I've created the edmx file and then the DBContext (the new 4.1 feature) classes. all went well.
Then, I've created new controllers using the automatic creation for DBContext. All wen't great.
Now, that I'm trying to fire up the website it won't connect to the connection string itself created.
Here is the connection string:
<add name="PizzaByMeEntities"
connectionString='metadata=res://*/Models.PizzaByMeModel.csdl|
res://*/Models.PizzaByMeModel.ssdl|
res://*/Models.PizzaByMeModel.msl;
provider=System.Data.SqlClient;
provider connection string="data source=(local);
initial catalog=PizzaByMe;
integrated security=True;
pooling=False;
multipleactiveresultsets=True;
App=EntityFramework;"'
providerName="System.Data.EntityClient" />
When I fire up the website I get:
A network-related or instance-specific error occurred while
establishing a connection to SQL Server. The server was not found or
was not accessible. Verify that the instance name is correct and that
SQL Server is configured to allow remote connections. (provider: SQL
Network Interfaces, error: 26 - Error Locating Server/Instance
Specified)
The strange part is that if I remove the connection string - I still get the exact same error. I guess that the EF just can't find the Connection String even when it's there.
Any ideas?
Thanks!
EDIT:
My DBContext is as follows:
public partial class PizzaByMeEntities : DbContext
{
public PizzaByMeEntities()
: base("name=PizzaByMeEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<X> Xs{ get; set; }
public DbSet<Y> Ys{ get; set; }
public DbSet<Z> Zs{ get; set; }
}
EDIT 2:
the working connection string is this:
<add name="PizzaByMe" connectionString="Data Source=(local);initial catalog=PizzaByMe;integrated security=True;pooling=False;multipleactiveresultsets=True;" providerName="System.Data.EntityClient" />
Though to make it work - I just used direct ADO.NET connection.
Your derived DbContext class must have the same name as your connection string if you have only implemented a default constructor (or no constructor at all)
public PizzaByMeEntities : DbContext
{
public PizzaByMeEntities()
{
// ...
}
}
If your context has another name then you must specify the name of the connection string in the constructor:
public PizzaByMeContext : DbContext
{
public PizzaByMeContext() :
base("name=PizzaByMeEntities")
{
// ...
}
}
Here are details about connections and connection strings with DbContext: http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-2-connections-and-models.aspx
Edit: Another guess
The connection string must be in the web.config of your MVC app, not in an app.config of a class library project where you possibly have your EF model and DbContext. Is it?
Phewwww.... figured it out!!!
The Context object that the controller created (when you use new context) it created the object without the constructor that chooses the connection string. So it tried to use some non-existing connection string.
For conclusion - any object deriving from DBContext should use a constructor that would specify the connection string.
Thanks guys for helping me out :))
I'm trying to use a custom role provider in an MVC3 app. I've already got the membership provider working ok using Ninject but can't seem to get the role provider working. The Membership provider doesn't require a parameterless constructor but role provider does. Here's some code snippets:
Web.config
<membership>
<providers>
<clear/>
<add name="MyMembershipProvider" type="MyApp.Models.NHibernateMembershipProvider"
applicationName="myApp" />
</providers>
</membership>
<roleManager enabled="true">
<providers>
<add name="MyRolesProvider" type="MyApp.Models.NHibernateRoleProvider"
applicationName="myApp" />
</providers>
</roleManager>
I have a Ninject module.
public class MyNinjectModule : NinjectModule
{
public override void Load()
{
this.Bind<ISession>().ToMethod(
x => MyApp.MvcApplication.SessionFactoryData.GetCurrentSession());
// Respository
this.Bind<IUserRepository>().To<UserRepository>();
this.Bind<MembershipProvider>().To<NHibernateMembershipProvider>();
this.Bind<RoleProvider>().To<NHibernateRoleProvider>();
}
}
The custom Membership provider
public class NHibernateMembershipProvider : MembershipProvider
{
private IUserRepository _repo;
public NHibernateMembershipProvider(IUserRepository repository)
{
_repo = repository;
}
...
The role provider
public class NHibernateRoleProvider : RoleProvider
{
private IUserRepository _repo;
public NHibernateRoleProvider(IUserRepository repository)
{
_repo = repository;
}
...
I then configure my controller to require an authorize
[Authorize(Roles="Admin")]
public ActionResult Edit(int? id)
{
...
I get this error when starting the app.
Parser Error Message: No parameterless constructor defined for this object.
Source Error:
Line 49: <roleManager enabled="true">
Line 50: <providers>
Line 51: <add name="MyRolesProvider" type="MyApp.Models.NHibernateRoleProvider"
Line 52: applicationName="myApp" />
Line 53: </providers>
I can access the users through the membership provider, so the repository is being injected ok, but the roles provider seems to be different. Why does the role provider require a constructor-less parameter? Is there a simple way to get the role provider to work with Ninject. Any help appreciated.
Since the role provider, in this case the NHibernateRoleProvider is instantiated by the ASP.NET framework the best solution is to use the service locator pattern. The service locator pattern is normally considered to be an anti-pattern but sometimes you have to be pragmatic and accepted the limitation on the framework that is being used (in this case the ASP.NET framework).
Assuming you are using an implementation of the IDependencyResolver interface for Ninject. The following code should work.
public class NHibernateMembershipProvider : MembershipProvider
{
private IUserRepository _repo;
public NHibernateMembershipProvider()
{
_repo = DependencyResolver.Current.GetService<IUserRepository>();
}
// ...
}
Alternatively, if you're using the Ninject.Web.Mvc nuget package you can always use property injection on your role provider as illustrated here:
ASP.NET MVC 3 Ninject Custom Membership and Role Provider