Changing dataset connection string in web config at runtime - asp.net

I have a c# generated dataset.
How can I change the connection string so I can use the dataset with another (identically structured yet differently populated) database?
This has to occur at runtime as I do not know the server or database name at compile time. I am using c# 3.5.

I think there is no simple way and you cannot change the Connection-String programmatically for the entire DataSet since it's defined for every TableAdapter.
You need to create the partial class of the TableAdapter to change the connection-string since the Connection property is internal (if your DAL is in a different assembly). Don't change the designer.cs file since it will be recreated automatically after the next change on the designer. To create it just right-click the DataSet and chose "show code".
For example (assuming the TableAdapter is named ProductTableAdapter):
namespace WindowsFormsApplication1.DataSet1TableAdapters
{
public partial class ProductTableAdapter
{
public string ConnectionString {
get { return Connection.ConnectionString; }
set { Connection.ConnectionString = value; }
}
}
}
Now you can change it easily:
var productTableAdapter = new DataSet1TableAdapters.ProductTableAdapter();
productTableAdapter.ConnectionString = someOtherConnectionString;
Here's a screenshot of my sample DataSet and the created file DataSet1.cs:

ide mvs 2008
in your settings.designer.cs verifier or edit this
public string NamOfappConnectionString{
get {
return ((string)(this["NamOfappConnectionString"]));
}
//add this line
set {
this["NamOfappConnectionString"]=value;
}
}
//atr untime use this
string myconnexion = "Data Source=" + txt_data_source.Text + ";Initial Catalog=" + txt_initial_catalog.Text + ";Persist Security Info=True;";
ConfigurationManager.AppSettings.Set("NamOfappConnectionString", myconnexion);
//save into setting
Properties.Settings.Default.NamOfappConnectionString= myconnexion;
Application.Restart();

Related

Tridion 2009 SP1: Is it possible to publish a .htaccess file?

I am using ISAPI rewrite on a project and would like to know if it is possible to publish a .htaccess file from Tridion?
I have tried creating a Page Template with the .htaccess extension but can't create a page with no name.
Any ideas?
Could I use a C# TBB to change the page name?
I would also choose to use a binary to achieve this, but if you want to manage the htaccess file using text, rather than as a multimedia component, you can push a binary into your package using the following technique:
1) Push the text of the Htaccess file into the package with an accessible name (i.e. Binary_Text)
2) Use code similar to the following to create a text file from the text in the variable and add it to the package
class publishStringItemAsBinary : ITemplate
{
public void Transform(Engine engine, Package package)
{
TemplatingLogger log = TemplatingLogger.GetLogger(typeof(publishStringItemAsBinary));
TemplateUtilities utils = new TemplateUtilities();
System.IO.Stream inputStream = null;
try
{
string strInputName = package.GetValue("InputItem");
string strFileName = package.GetValue("strFileName");
string sg_Destination = package.GetValue("sg_Destination");
string itemComponent = package.GetValue("mm_Component");
inputStream = new MemoryStream(Encoding.UTF8.GetBytes(package.GetValue(strInputName)));
log.Debug("InputObject:" + strInputName);
log.Debug("Filename for binary:" + strFileName);
log.Debug("Destination StructureGroup:" + sg_Destination);
Publication contextPub = utils.getPublicationFromContext(package, engine);
TcmUri uriLocalSG = TemplateUtilities.getLocalUri(new TcmUri(contextPub.Id), new TcmUri(sg_Destination));
TcmUri uriLocalMMComp = TemplateUtilities.getLocalUri(new TcmUri(contextPub.Id), new TcmUri(itemComponent));
StructureGroup sg = (StructureGroup)engine.GetObject(uriLocalSG);
Component comp = (Component)engine.GetObject(uriLocalMMComp);
String sBinaryPath = engine.PublishingContext.RenderedItem.AddBinary(inputStream, strFileName, sg, "nav", comp, "text/xml").Url;
//Put a copy of the path in the package in case you need it
package.PushItem("BinaryPath", package.CreateStringItem(ContentType.Html, sBinaryPath));
}
catch (Exception e)
{
log.Error(e.Message);
}
finally
{
if (inputStream != null)
{
inputStream.Close();
}
}
}
}
I think the code is pretty self explanatory. This publishes a binary of type text/xml, but there should be no issue converting it to do a plain text file.
I think you can use multimedia component to store your .htaccess. Even if you will not be able to upload file without name (Windows limitation), you will be able to change filename later, by modifying BinaryContent.Filename property of multimedia component. You can then publish this component seperately, or use AddBinary method in one of your templates.
There's also a user schema where you can change some other rules: "\Tridion\bin\cm_xml_usr.xsd", but you will not be able to allow empty filenames

SQL statement's placeholders that is not replaced leads to "Cannot update '#columnName'; field not updateable"

I'm writing some code updating database with a SQL statement that has some placeholders . But it doesn't seem to update these placeholders.
I got the following error:
Cannot update '#columnName'; field not updateable
Here is the method:
public void updateDoctorTableField(string columnName, string newValue, string vendorNumber) {
sqlStatement = "update Doctor set #columnName = #newValue where `VENDOR #` = #vendorNumber;";
try {
_command = new OleDbCommand(sqlStatement, _connection);
_command.Parameters.Add("#columnName", OleDbType.WChar).Value = columnName;
_command.Parameters.Add("#newValue", OleDbType.WChar).Value = newValue;
_command.Parameters.Add("#vendorNumber", OleDbType.WChar).Value = vendorNumber;
_command.ExecuteNonQuery();
} catch (Exception ex) {
processExeption(ex);
} finally {
_connection.Close();
}
}
Not all parts of the query are parameterisable.
You can't parametrise the name of the column. This needs to be specified explicitly in your query text.
If this is sent via user input you need to take care against SQL Injection. In fact in any event it would be best to check it against a whitelist of known valid column names.
The reason the language does not allow for parameters for things like table names, column names and such is exactly the same reason why your C# program does not allow for substitution of variables in the code. Basically your question can be rephrased like this in a C# program:
class MyClass
{
int x;
float y;
string z;
void DoSomething(string variableName)
{
this.#variable = ...
}
}
MyCLass my = new MyClass();
my.DoSomething("x"); // expect this to manuipulate my.x
my.DoSomething("y"); // expect this to manuipulate my.y
my.DoSomething("z"); // expect this to manuipulate my.z
This obviously won't compile, because the compiler cannot generate the code. Same for T-SQL: the compiler cannot generate the code to locate the column "#columnName" in your case. And just as in C# you would use reflection to do this kind of tricks, in T-SQL you would use dynamic SQL to achieve the same.
You can (and should) use the QUOTENAME function when building your dynamic SQL to guard against SQL injection.

programmatically change table names in .net strong typed dataset

hi
I've developed an application using strong-typed dataset with .net framework 3.5.
is there a way to change the source table for a tableadapter programmatically?
thnx
There are a couple of ways that you can do this. First you could just add a new query that pulls from the different table, and then execute the method for that query, as long as the columns match it will work.
If you need to dynamically change the one of the statements you can access the command collection of the table adapter, it is protected though, so the easiest way to do this is to create a partial class to extend the one generated by the designer. Once you do this you can add your own method to return the data. You can use adapter.CommandCollection[0].CommandText to get and set the SQL for the the default GetData command that is created.
Once you do this you can change it, clear out the parameters, add new parameters or whatever you want to do, then you set the CommandText with the altered SQL, and call GetData or whatever you named the command and it will execute and return as usual.
Here is a code example:
using System.Data.SqlClient;
namespace DataTableAdapters
{
public partial class Data_ItemTableAdapter
{
public Data.Data_ItemDataTable GetDynamicExample(string SearchValue)
{
using (Data_ItemTableAdapter a = new Data_ItemTableAdapter())
{
SqlCommand cmd = a.CommandCollection[0];
cmd.Parameters.Clear();
string SQL = #"Select Data_Item_ID, Data from Data_Item where
SearchValue = #SearchValue";
cmd.CommandText = SQL;
cmd.Parameters.AddWithValue("#SearchValue", SearchValue);
return a.GetData();
}
}
}
}

subsonic 3.0.0.3 multiple database connection failover

am using MVC and Subsonic 3.0.0.3 but i cant seem to pin down a specific point for multiple database connection.
normally in normal .net i would have my 2 strings in the web.config file
and have a database class for my project, within this db class i would do something like this:
try
{
conn.ConnectionString = server1;
conn.Open();
}
catch (MySqlException)
{
conn.ConnectionString = server2;
conn.Open();
}
I am trying to pin down the one place in subsonic's created files where something like this would be best to place and maybe an up to date example on how to achieve it. I have googled etc but the examples shown are for an older subsonic.
many thanks
If you look in Context.tt at line 35 you'll see the following code:
public <#=DatabaseName#>DB()
{
DataProvider = ProviderFactory.GetProvider("<#=ConnectionStringName#>");
Init();
}
This is where the provider is getting setup for you so if you add a BackupConnectionStringName variable in Settings.ttinclude after the ConnectionStringName at line 20 then you should be able to check your connection is working and user your fallback if not. For example:
public <#=DatabaseName#>DB()
{
DataProvider = ProviderFactory.GetProvider("<#=ConnectionStringName#>");
Init();
try
{
DataProvider.CreateConnection();
}
catch(SqlException)
{
DataProvider = ProviderFactory.GetProvider("<#=BackupConnectionStringName#>");
Init();
}
}
NB You may need to do some clean up to make sure a connection is not left open by CreateConnection.

Is there a way to get ALL the MIME types instead of wrinting a huge case statement?

I want to populate
Response.ContentType = "text/plain";
From somewhere in the server/web/dictionary ALL possible MIME types according to file extension:
public string GetMimeType(string extension)
{
//This is what I am looking for.
}
Also, I have to rename the file (at least if going to be downloaded, so I have to know in advance if it's going to be opened or not.
You can store the mimetype when the file is uploaded ( FileUpload.PostedFile.ContentType ) and send that when the file is requested.
Umm... why? You're not going to be returning content of every possible type, are you?
Here's a list of common types: http://www.webmaster-toolkit.com/mime-types.shtml. There is no list that would include "ALL" types simply because any application vendor can create a custom one and associate it with a custom extension.
It's going to depend on your platform. Here's one for C# and IIS: http://blog.crowe.co.nz/archive/2006/06/02/647.aspx
In Powershell it's a one-liner:
([adsi]"IIS://localhost/MimeMap").MimeMap
The code in the link posted by Richard:
// Maintain a sorted list to contain the MIME Types
SortedList sl = new SortedList();
Console.WriteLine("IIS Mime Map - c#");
Console.WriteLine();
// Serve to connect to...
string ServerName = "LocalHost";
// Define the path to the metabase
string MetabasePath = "IIS://" + ServerName + "/MimeMap";
// Note: This could also be something like
// string MetabasePath = "IIS://" + ServerName + "/w3svc/1/root";
try
{
// Talk to the IIS Metabase to read the MimeMap Metabase key
DirectoryEntry MimeMap = new DirectoryEntry(MetabasePath);
// Get the Mime Types as a collection
PropertyValueCollection pvc = MimeMap.Properties["MimeMap"];
// Add each Mime Type so we can display it sorted later
foreach (object Value in pvc)
{
// Convert to an IISOle.MimeMap - Requires a connection to IISOle
// IISOle can be added to the references section in VS.NET by selecting
// Add Reference, selecting the COM Tab, and then finding the
// Active DS Namespace provider
IISOle.MimeMap mimetypeObj = (IISOle.MimeMap)Value;
// Add the mime extension and type to our sorted list.
sl.Add(mimetypeObj.Extension, mimetypeObj.MimeType);
}
// Render the sorted MIME entries
if (sl.Count == 0)
Console.WriteLine("No MimeMap entries are defined at {0}!", MetabasePath);
else
foreach (string Key in sl.Keys)
Console.WriteLine("{0} : {1}", Key.PadRight(20), sl[Key]);
}
catch (Exception ex)
{
if ("HRESULT 0x80005006" == ex.Message)
Console.WriteLine(" Property MimeMap does not exist at {0}", MetabasePath);
else
Console.WriteLine("An exception has occurred: \n{0}", ex.Message);
}
// Convert to an IISOle.MimeMap - Requires a connection to IISOle
// IISOle can be added to the references section in VS.NET by selecting
// Add Reference, selecting the COM Tab, and then finding the
// Active DS Namespace provider
According to my googling: (lost the links, sorry)
The "Active DS IIS Namespace Provider" is part of the IIS installation.
After you install IIS you will see that in the list of options.
If you don't see it should be located at C:\windows\system32\inetsrv\adsiss.dll.
To install IIS:
click Start, Settings, Control Panel, Add or Remove Programs, Add or Remove Windows Components, select Internet Informatoin Services (IIS).
Most of the code I've seen uses some combination of these:
using System.IO;
using System.DirectoryServices; // Right-click on References, and add it from .NET
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;
using IISOle;
using System.Collections.Specialized;
The Active DS Namespace might be under the COM tab when adding the reference.
I've written a small class based on the webmaster-toolkit.com list. This is to avoid using COM and the IIS route or any IIS references.
It uses an XML serialized list which contains about 400 mimetypes, so is usually more than enough unless you have really obscure mimetypes. In that case you can just add to the XML file.
The full solution can be found here. Here's a sample:
class Program
{
static void Main(string[] args)
{
var list = MimeType.Load();
MimeType mimetype = list.FirstOrDefault(m => m.Extension == "jpg");
}
}

Resources