I'm wondering whether it's possible to use built in ASP.NET application services (aspnet_user, aspnet_role etc table) without specifying a connection string in a web.config.
At the moment I store connection strings externally, but I keep finding hard-coded connection strings all over the web.config xml, various providers etc. It's driving me crazy.
Thank you
You can write your own provider via overriding already existed, built-in class so it will read it's connection string from somewhere else:
public class MyMembershiProvider : SqlMembershiProvider
{
public override void Initialize(string name, NameValueCollection config)
{
config["connectionString"] = "what ever you want";
base.Initialize(name, config);
}
}
Related
I am writing an application using ASP.NET webforms with login dialog. After successfull authentication the connection is opened, but connection object is not visible from other webforms. Is there any way to make it persistent and accessible (in some server session objects), or is it commonly done in another way ? Any tips appreciated.
The best way is to open/close the connection where you want to use it. Don't share it and never use a static connection in ASP.NET which is a multi-threading environment. You should use the using statement for all objects implementing IDisposable which ensures that all unmanaged resources are disposed. This will also close the connection, even on error:
using(var con = new SqlConnection("connection string here"))
{
// do something ...
}
You don't need to be afraid that the physical connection must be opened/closed everytime. The .NET connection pool will handle that for you. Related
A simple example.
Set up a class to handle the SqlConnection object (or whatever DB you're using):
DbConnectionProvider.cs
using System.Data.SqlClient
public class DbConnectionProvider
{
public static SqlConnection GetDbConnection()
{
return new SqlConnection("MyConnectionString");
}
}
Then from all classes that needs to use the database
ApplicationClass.cs
using System.Data.SqlClient
public class ApplicationClass
{
private void GetSomeDbWorkDone()
{
using(SqlConnection Conn = DbConnectionProvider.GetDbConnection())
{
//Do some fancy database operations here
}
}
}
This way, if you need to change your Connection details or do something else regarding the SqlConnection object, you only need to do it once and not everywhere in your code.
Is it possible to change a parameter name of an asmx web service without breaking clients? For example, consider a legacy service which has a web method like so:
[WebMethod]
public string HelloWorld(string NAME)
{
return "Hello World and " + NAME;
}
The legacy service web method has the parameter NAME, but I'd like to change this to 'Name' to follow coding guide-lines. Will this break existing clients?
The simplest might be to add a new method
//New clients use this Maybe you put it in a new asmx file.
[WebMethod]
public string Hello_World(string FullName)
{
return HelloWorld(FullName);
}
//Old clients use this.
[WebMethod]
public string HelloWorld(string NAME)
{
return "Hello World and " + NAME;
}
WCF has ways of having a Method name and parameter be one thing, but the xml be another using annotations. I think there is a way to create a WCF service that can talk to legacy ASMX clients, I haven't tried it. In that scenario you could rename all your methods and parameters and via attribute annotations, maintain the old names for the xml across the wire.
I'm building an ASP.NET MVC3 Website with EF and DB First Approach. I need to come up with a reliable mechanism for database context switching in runtime for users. I've got several databases (same schema) that are used in remote "workshops" and application users in company headquaters need to have the ability to switch between databases at any time.
First I have implemented a base controller, that had ChangeDbContext(string dbname). It was persisting selected dbName to Session, and then I was retrieving from Session in OnActionExecuting method. However it turned out to be not reliable because session behaved unpredicatble (random expiration etc.) So I'm looking a smart way to replace Session with something else.
I could use advices on :
- where to put EntityFramework object initialization (BaseController Constructor ?)
- are there any additional changes that I should do to utilize Impersonation with WindowsAuth for DB connection ?
First, you need to insure your application session can survive restarts and app pool recycles. See this
Second, you need to inject the connection string for your DBContext based on the authenticated user request.
I assume you’ve got a database full of users so what you need to do is save a list of possible connection strings in a SQL table and relate them back to their associated user accounts. Once you’ve authenticated the user you need to retrieve the connection string associated with the user account. You don't want to store your connection string in a session or any other mechanism that could potentially expose sensitive data to a web client. So in summary this what you need to do.
You will want to retrieve your connection string for each request base on the authenticated user.
Inject the connection string into your DBContext.
Make your database calls as necessary.
Money!
Injecting strings into entity is easy.
If you're using EF 4.1 Code first your DBContext would look something like this.
EF 4.1 accepts normal ADO.NET connection strings.
public class ExampleProvider : DbContext, IExampleProvider
{
private readonly string _nameOrStringConnection;
public ExampleProvider()
{
}
public ExampleProvider(string nameOrStringConnection)
: base(nameOrStringConnection)
{
_nameOrStringConnection = nameOrStringConnection;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Example>().ToTable("example");
modelBuilder.Entity<Example>().HasKey(x => x.ExampleId);
}
public DbSet<Example> Examples { get; set; }
}
If you're using EF.edmx you will need to make sure that your injected connection string includes the edmx metadata files info like this...
..."metadata=res:///ExampleModel.csdl|res:///ExampleModel.ssdl|res://*/ExampleModel.msl;...
If you look in the edmx designer file you will see your DBContext has several constructor overloads. Use the second or third overload per your needs.
#region Contexts
/// <summary>
/// No Metadata Documentation available.
/// </summary>
public partial class Entities : ObjectContext
{
#region Constructors
/// <summary>
/// Initializes a new Entities object using the connection string found in the 'Entities' section of the application configuration file.
/// </summary>
public Entities() : base("name=Entities", "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
/// <summary>
/// Initialize a new Entities object.
/// </summary>
public Entities(string connectionString) : base(connectionString, "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
/// <summary>
/// Initialize a new Entities object.
/// </summary>
public Entities(EntityConnection connection) : base(connection, "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
#endregion
/// incomplete file
Good luck!
Cookies can be persisted for a long expiry, well longer than a session anyway. You could also look at a hidden page variable or mangled URL.
1) Sessions doesn't expire randomply...but after the time you set in the we.config...default is 10 min. Seesion MUST expire because there is no way to know that an user left our web site...so if they stop accessing pages for, say 10 min, we ASSUME, they went away...You can increase this time but the problem remain.
2) Tou can store directly the information in a cookie. Now since the cookie only waste resources on the browser (very little space), you can make the cookie persistent...so that it never expire
3) As an alternative to cookies you can store this information together with the credential information of users (login name etc.) You can use the Profile provider to define a property DBChosen.
We may never know why Microsoft decided to limit developers by making HealthVault applications constrained to a single web/app.config entry for a HealthVault application. However I need to be able to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
I won’t go into the details of the reasoning behind 2 different HealthVault applications, but other than to say we need it to work. I still cannot login correctly with MSDN Forums (think infinite redirection sign in loop) so I am hoping for a post here that will help me.
I did contact a HealthVault developer on how to achieve this however the developer gave a suggestion that I don’t believe would be reliable (if I’m wrong let me know).
The developer’s suggestion was to do the following in code when you needed to connect to HealthVault, but prior to connecting:
ConfigurationSettings.AppSettings[“ApplicationId”] = “[YOUR APP ID]”;
The problem is that this is a static property and I do see this as an issue as our web application will have different users accessing both HealthVault applications at the same time.
Does anyone have any suggestions to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
There is a way to dynamically switch app ids on runtime. Both applications must be created, both certificates must be installed. Few things to keep in mind. For every authenticated connection, user will be granted a token (aka wctoken). This token is consumed when user is redirect back from Live ID (in case live id is used...) by your redirect.aspx page (assuming your redirect page inherits from HealthServiceActionPage.This means that everytime you switch applications, you must redirect user back to Live ID with new app id to receive new token.
Here is code sample that can be user to dynamically change settings:
public class ConfigurationManager : HealthWebApplicationConfiguration
{
private string appid;
public ConfigurationManager(string appid)
{
this.appid = appid;
}
public override Guid ApplicationId
{
get
{
return AppManager.Current.GetCurrentAppId(this.appid);
}
}
}
public class AppManager
{
private static readonly Object lck = new Object();
public Guid? App;
public static AppManager Current
{
get
{
AppManager mgr = null;
if (_current == null)
{
lock (lck)
{
mgr = new AppManager();
}
}
return mgr;
}
}
private static AppManager _current;
public Guid GetCurrentAppId(string id)
{
return new Guid(id);
}
}
Usage:
ConfigurationManager cm = new ConfigurationManager(your-app-id-here);
HealthWebApplicationConfiguration.Current = cm;
I want to seperate the data module of a site into an assembly ( a single dll file ) ,
What is the best way to get-store and pass the ConnectionString of the site in dealing with the web application .
Inside the data assembly I made a static class named ConnectionManager . It has a property named DatabaseConnectionName , that I want to pass and store the connection namewhich is inside Web.Config file .
In this strategy I decided to get the name and make the connection in the load time of the website at the Global.asax file and stroe that in the property I mentioned earlier ( DatabaseConnectionName ) .
But , This is just the strategy that I used , I dont know what is the common pattern for doing this job .
Parts of code : =====================================
[ ------------ Global.asax ------------ ]
the code in the site that makes the Data module accessible for the site
void Application_Start(object sender, EventArgs e)
{
OurCompany.Data.ConnectionManager.DatabaseConnectionName = "MasterConnection";
}
[ ------------ ConnectionManager Class ------------ ]
this is in the data module apart from the site
public static class ConnectionManager
{
public static SqlConnection GetMasterConnection()
{
string connectionString = ConfigurationManager.ConnectionStrings[**DatabaseConnectionName**].ConnectionString;
SqlConnection conn;
//conn.Open();
conn = new SqlConnection(connectionString);
return conn;
}
private static string **databaseConnectionName**;
public static string DatabaseConnectionName
{
get
{
return databaseConnectionName;
}
set
{
databaseConnectionName = value;
}
}
== END ===========================================================
--- Questions are : ---
Where to store the connection ?
( here was a property inside the ConnectionManager Class ,
theCompany.Data.ConnectionManager.DatabaseConnectionName )
When make this connection ?
( here was at Global.asax Application Load time )
Which method is best for storing such information
: SessionState or ViewState or a simple property
Is this strategy good ? Do you know any better way or
the common pattern for this ?
Thanks for any information
- MHM -
A few thoughts...
You shouldn't be storing and hanging onto an open database connection. Open the connection, do your database operations, then close immediately. Apply the rule of acquire late, release early.
See point 1.
Don't store database connections in session state. See point 1 again. If you mean the connection string, then just read it from the configuration manager when you need it. It's already cached for you, don't re-invent or wrap the wheel.
I suggest you take a look at the patterns and practices enterprise library which abstracts away many of the common patterns of managing data access:
http://www.codeplex.com/entlib