Custom Entity Framework configuration file - c#

I am using Entity Framework. The connection string is currently saved in the app.config file, which by default creates a new file called APPLICATION_NAME.exe.config and copies it to the output folder when building.
Now I don't want my connection string to be visible to the world when I am creating applications, so one way is to create another config file as a resource and reference it in the application.
EDIT:
I am developing using WPF, now is there any special configuration for it doing the below:
How to register an embedded config file in the application ?
Normally when you create your own DbContext, you pass the connection string like this
public MyDBContext() : base("name=Connection_String_Name_In_AppConfig")
so how to tell the DbContext classes to take the connection string from the newly created config file?

Q1. How to register an embedded config file in the Application
You do not. But nothing stops you do "program" code that takes your own configuration information from wherever you want and uses that.
Q2. How to tell DBContext classes to take the DB connection from the newly created config
file ?
You do not. But you can actually pass in an code created connection toe a DbCOntext, in case you did not see that in the documentation.
And seriously, NOTHING in here has ANY relationship to WPF, so that tag you added is just not a good smart move.

To embed a file into the assembly, select the file in the solution explorer and go to Property window then select Build Action as 'Embedded Resource' and Copy to Output Directory as 'Do not copy'. This way the XML config file will get embedded in the assembly.
Now in your Host application(here WPF), you can read the resource file content and then pass the connection string data to your DBContext.
Example to read embedded file from the assembly:
private const string strFileName = “XMLFile.config”;
var assembly = Assembly.GetExecutingAssembly();
var stream = assembly.GetManifestResourceStreamthis.GetType(), strFileName);
var doc = new XmlDocument();
try
{
if (stream == null)
{
throw new FileNotFoundException(“Couldnot find embedded mappings resource file.”, strFileName);
}
doc.Load(stream);
}
catch (Exception ex)
{
throw ex;
}
Hope this will help you
I have a sample application hosted on Github that exactly does what you want.

Related

Retrieve a custom configuration section

I want to make a library that will be used by either an exe (app.config) or a website (web.config). If I create a custom configuration section, and load it using
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CustomSection section = config.Sections.OfType<CustomSection>().FirstOrDefault();
it won't run on web site. It throws a exePath must be specified when not running inside a stand alone exe. exception, since it's not an exe. I can use something like:
CustomSection db = (CustomSection )ConfigurationSettings.GetConfig("CustomSection");
But that relies on the section being properly named. Is there a way to get all the sections and iterate through them?

ASP.NET file upload doesn't work in windows azure

I have write some codes for upload file in ASP.NET MVC3 project. In stead of storing file in database, I have uploaded the files in file system and stored the paths in database.
The codes for upload is as follows:-
if (file != null && file.ContentLength > 0)
{
if (path == null)
{
throw new ArgumentNullException("path cannot be null");
}
string pFileName = PrefixFName(file.FileName);
String relpath = String.Format("{0}/{1}", path, pFileName);
try
{
file.SaveAs(Server.MapPath(relpath));
return pFileName;
}
catch (HttpException e)
{
throw new ApplicationException("Cannot save uploaded file", e);
}
}
After saving the file I have used that image with image tag in several views. My codes works fine in local. But when I have hosted the site in windowsazure.com all things are working but the file upload.
How can I get rid of this situation? Please help.
One of the things you need to be aware of before trying to save the file is to ensure that the directory that you are wanting to save the file in exists. Here is a code snippet to ensure the target directory has been created on the target server.
var path= Server.MapPath("~/ImagesDirectory");
if (!System.IO.Directory.Exists(path))
{
System.IO.Directory.CreateDirectory(path);
}
You may want to wrap this is a try/catch to ensure your application has the NTFS privileges to write and create directories in that location. Also, ensure that your path variable is rendering out the path that you think it should be.
Also, if the directory exists in your VS project, but does not have any content in it, then the compiler will not create that directory. To ensure the directory is created when you upload a project, insert an empty text file, such as "_doNotDelete.txt" into that directory and set it's build action to content. This will ensure the directory will be created when you do a publish.
First you should not use web application's folder beside temporary operations. Since Azure means multi-computer environment, resource (image) won't be available for requester if you use more than one instance (machine)
Let's say you uploaded on instance A's local, instance B's local won't have that file and retrieving path from DB won't change anything for instance B. You would never know which instance will give the response to request. (well, you can but it is out of the scope here) But at the end you have to realize that your upload request may go to instance A and your display request may go to instance B which will not be able to retrieve.
Anyway, the best practice is use directly blobs, their whole purpose is this. You may find more details on http://www.windowsazure.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs-20/
But if you insist on using local path and have no problem losing files (yes it will happen) use Server.MapPath("~/App_Data/...")

Need changable App.config file in WPF

I have a desktop WPF application which uses Entity Framework 4.1 Code First approach to manage data.
EF adds a connection string to the App.config file and I wan't to be able to change this connection string at runtime.
Scenario is like this:
When I deploy the application it has a default connection string in the App.config file. The user runs the application and since the connection string will probably be invalid for the user (because of server name, user id and password) I will display a server configuration window.
Here user will enter the valid information about his connection and press OK. I will then be able to change the App.config file and save the user's new valid information to the file.
Problems:
If I change it using ConfigurationManager, the changes will be temporary meaning that the file is not saved, changes are made in memory.
If I read the App.config file into a stream, make required changes in the memory, delete physical file and save the in memory stream as App.config again, Windows will not let me make changes to files under ProgramFiles folder.
What is would be the best approach here?
EDIT: Problem Again!
After I modify the App.config file with this method:
private void ApplyChangesToConnectionString()
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
connectionStringsSection.ConnectionStrings["SomeUniqueName"].ConnectionString = GetChangesAppliedConnectionString(connectionStringsSection.ConnectionStrings["SomeUniqueName"].ConnectionString);
config.Save(); // This line throws an exception
ConfigurationManager.RefreshSection("connectionStrings");
}
config.Save(); method call throws an error saying
"Access to "C:\Program Files (x86)\MyCompany\MyApp\MyApp.exe.config"
is denied."
I know that files under "Program files" are immutable, so how can I handle this?
I couldn't modify ConfigurationManager.ConnectionStrings["key"] object, because it is readonly.
So I decided to add a new connection string to my App.config file so it looks like this:
<connectionStrings>
<add name="SomeUniqueName" connectionString="Data Source=(local)\SQLExpress;Initial Catalog=MyDb;User Id=sa;Password=password; MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
and then changed my DbContext constructor to take newly added connection string like this:
public MyContext()
: base("name=SomeUniqueName")
{
}
Here, the value of name attribute at connection string and constructor must match.
Then to change this newly added connection string at runtime I used a method like this:
private void ApplyChangesToConnectionString()
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
connectionStringsSection.ConnectionStrings["SomeUniqueName"].ConnectionString = GetChangesAppliedConnectionString(connectionStringsSection.ConnectionStrings["SomeUniqueName"].ConnectionString);
config.Save();
ConfigurationManager.RefreshSection("connectionStrings");
}
App.config is not the proper place to do this since it's a global configuration used by the application.
I recommend you to save the settings per user. See this related question : c# - approach for saving user settings in a WPF application?
App.config is the correct approach in my opinion, however I wouldn't rely on writing the file physically yourself. Instead, allow the framework to do the heavy lifting for you.
Check out the sample here.
EDIT: Glad Sandeep's comment above has helped you. Feel free to check out that link too if you want a bit more information!

MVC3 application: What folder to use for saving files on the server?

I have an application MVC3 application. I want to log various things, like when a form particular form is submitted, to avoid having to write to a database, I want to log the details in an xml file.
The question is what folder should I use, some of the examples I have seen suggest the App_Data folder. What is the norm or recommended for the least issues?
So I use this:
// Create a new XmlSerializer instance with the type of the test class
var serializerObj = new XmlSerializer(typeof(CourseApplicationVM));
// Create a new file stream to write the serialized object to a file
var filename = string.Format("{0}-{1}-{2}{3}", "CourseApp",
viewModel.Course.Code + viewModel.Applicant.Name, DateTime.Now.Ticks, ".xml");
var filepath = Path.Combine(Server.MapPath("~/App_Data/Log"), filename);
TextWriter writeFileStream = new StreamWriter(filepath);
serializerObj.Serialize(writeFileStream, viewModel);
// Cleanup
writeFileStream.Close();
It works fine locally, but not when published to the server. Upon looking at the folder structure it is unsurprising, as it doesn't even have the App_Data folder when published. Which leads to this error:
Could not find a part of the path 'C:\inetpub\wwwroot\MyApplication\App_Data\Log\CourseApp-0385JoeBloggs-634734549879496695.xml'.
Exception Details: System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\inetpub\wwwroot\MyApplication\App_Data\Log\CourseApp-0385JoeBloggs-634734549879496695.xml'.
Why is it that is hasn't got that folder (shouldn't it be published up)? And what is the normal location for the saving of such things?
Thanks,
David
Right Click on the folder and in context menu select "Include in to project/solution"
Make sure you rights on folder are set accordingly.

Edit parameters in Settings file

I have DataClasses.dbml file in my C# winforms project. This automatically adds a setting of type ConnectionString to Settings file of the project. The connection string throughout the project is accessed using this setting.
Now when I work on my PC, it connects to the database and works fine. But how to set a new connection string depending on client's host and instance names in the settings file permanently and for once (during setup).
I tried doing:
Settings.Default.ConnectionString = "SqlConnectionString";
Settings.Default.Save();
But it gives a compile-time error that its Read-Only.
My only aim is to set the connectionstrings according the clients setting. I dont want to make it hard coded.
Add a partial class definition like the following
public partial class DataClasses
{
partial void OnCreated()
{
Connection.ConnectionString = SQLHelpers.GetConnectionStr();
}
}
where SQLHelpers.GetConnectionStr should lookup the settings from the users App.Config file.
Remember to put this in a separate file to your auto-generated dbml file.

Categories