How to use two connection strings on development vs production - mysql

I have two connection strings in my Web.config.
<connectionStrings>
<add name="AuthContext" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=mokey;Integrated Security=True" providerName="System.Data.SqlClient" />
<add name="AuthContextMySQL" providerName="MySql.Data.MySqlClient" connectionString="database=mokey;persistsecurityinfo=True" />
</connectionStrings>
I can specify which one to use in code like this:
public class AuthContext : IdentityDbContext<IdentityUser>
{
public AuthContext()
: base("AuthContextMySQL")
{
}
}
How do I specify which one to use depending on development vs production?

You can use web.config transformations during your build step to add/update/delete sections of your web.config depending on the build configuration. See this article for a step by step guide.

Related

Web.config equivalent to “using static MyClass;” in <add namespace=“MyClass” />

In ASP.Net, you can add a namespace to all Razor views by adding the following code to the View folder’s Web.config:
<system.web.webPages.razor>
<namespaces>
<add namespace=“MyClass” />
</namespaces>
</system.web.webPages.razor>
This is equivalent to putting the statement “using MyClass;” at the top of a C# file.
However, how would I add a namespace to Web.config as a “static” class, where I can access the class’s methods directly within views without having to write out “MyClass.MyMethod();” for example?
You can already do this by putting the statement “using static MyClass;” at the top of a C# file (C# 6 is required, see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-static).
It just appends whatever it is you put as namespace. Just needs to append the static keyword to the namespace.
So as you pointed out <add namespace=“MyClass” /> is equivalent to using MyClass;
Change to <add namespace=“static MyClass” />, which is equivalent to using static MyClass;
In your case:
<system.web.webPages.razor>
<namespaces>
<add namespace=“static MyClass” />
</namespaces>
</system.web.webPages.razor>
should be what you're looking for

How use MySQL membership in mvc4 code first application?

I am new in MVC with MySQL. I have code first application in MVC 4 with MySQL.
public class Category
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public virtual IEnumerable<Product> Products { get; set; }
}
public class Product
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public DateTime CreateDate { get; set; }
public int CategoryID { get; set; }
public virtual Category Category { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
}
And in web.config:
<connectionStrings>
<add name="MyContext" connectionString="server=localhost; User Id=root; Pwd=mypass; Persist Security Info=True; database=catalogue" providerName="MySql.Data.MySqlClient " />
</connectionStrings>
So, this creates catalogue database in mysql. But i want also to use membership of mysql. To register, to create users and manage their roles.
For example, using default AccountModels of mvc4
I added this code to web.config:
<system.web>
<membership defaultProvider="MySQLMembershipProvider">
<providers>
<clear />
<remove name="MySQLMembershipProvider" />
<add name="MySQLMembershipProvider" type="MySql.Web.Security.MySQLMembershipProvider, MySql.Web, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" applicationName="/" description="MySQL default application" connectionStringName="LocalMySqlServer" writeExceptionsToEventLog="True" autogenerateschema="True" enablePasswordRetrieval="True" enablePasswordReset="True" requiresQuestionAndAnswer="False" requiresUniqueEmail="False" passwordFormat="Clear" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
</providers>
</membership>
<profile defaultProvider="MySQLProfileProvider">
<providers>
<clear />
<remove name="MySQLProfileProvider" />
<add name="MySQLProfileProvider" type="MySql.Web.Profile.MySQLProfileProvider, MySql.Web, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" applicationName="/" description="Profiles" connectionStringName="LocalMySqlServer" writeExceptionsToEventLog="False" autogenerateschema="True" />
</providers>
</profile>
<roleManager enabled="false" defaultProvider="MySQLRoleProvider">
<providers>
<clear />
<remove name="MySQLRoleProvider" />
<add name="MySQLRoleProvider" type="MySql.Web.Security.MySQLRoleProvider, MySql.Web, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" applicationName="/" description="Project Roles" connectionStringName="LocalMySqlServer" writeExceptionsToEventLog="True" autogenerateschema="True" />
</providers>
</roleManager>
</system.web>
When run application I get this error:
Which step have I forgot? I cant use membership.
(Sorry for bad English)
If what you want is to use the Membership Provider that comes shipped with MVC4 Internet Templates of VS2010 or VS2012, with a database other than SQL Server Family, namely SQL Server, SQL Compact and Azure, I think that is not feasible, since MVC4 uses SimpleMembership provider, which is not Database Agnostic.
Have said that, that doesn't mean that you can't achieve what you want. I propose to use Microsoft ASP.NET Universal Providers Core Libraries. I recommend that you read this excellent Post
Now in this article the author, Scott Hanselman, mentions the following
Using these Universal "Default Profile Providers" means all you have to do is set the right connection string and your applications that use these services will work with SQL Server (plus Express), SQL Server Compact and SQL Azure with no code changes from you.
Hmmm and how about other SQL Standards?, well let's follow these steps,
1) Make sure to change the connection string first, and then with the Nuget Package Manager, install MySQL.Web, and MySQL.Data.
<connectionStrings>
<add name="MySQLConn" connectionString="Server=localhost;Database=dbname;Uid=dbuser;Pwd=dbpass;" />
</connectionStrings>
2) With the Nuget Package Manager find and install the "Microsoft ASP.NET Universal Providers Core Libraries" or run the following commands in the Package Manager Console,
Install-Package system.web.providers
Install-Package Microsoft.AspNet.Providers.Core
3) Go to Project Menu -> ASP.Net Configuration, you will see in the browser ASP Net Administration tool for your web project.
4) Then go to Provider Tab, Go to "Select a different provider for each feature (advanced)"
5) Make sure to select MySQL Membership Provider.
6) Then go Security Tab, and create some Roles and Users that you consider necessary for your project.
If for some reason you get an error here, try changing your web config, and replace Membership, Role and Profile with this
7) Enjoy!
I hope this helps
PS: I'm very new on this too, so I'm open to suggestion about the best Membership Provider for MVC4 that targets others SQL Databases.
As a side note, you can not use the same Account Controller, of the Internet Template of ASP Net MVC3 or MVC4 of VS2010 or VS2012. Though you have to implement that all by yourself.
You can use for example Security Guard if you want to quickly add MVC template for Login/Logoff/Role Administration/Create Users etc.
The method that I proposed is not a patch nor is hackerish, ASP Net Membership Provider were long implemented and promoted by Microsoft and MySQL added the functionality to the Net. Connector, and they even have posted about it. Here
So fear not, you can safely use this method, unless there is a strong argument against using ASP Net Membership Provider, that I'm not aware of.
This is taken from GridWizzard - you just need set enableSimpleMembership to false under appsettings, http://gridwizard.wordpress.com/2014/03/05/asp-net-mvc4-just-get-it-running-without-having-to-implement-membershiproleprovider/

Azure role configuration management

I don't see how Windows Azure lets you vary the configuration of an application when you have no choice but to hold configuration settings in web.config (or app.config).
For example...
Quite often projects will make use of a 3rd party library that makes heavy use of web.config. The use of web.config may involve connection strings, app settings or custom configuration sections. A good example of this is ELMAH. A web.config file for ELMAH might look like the following:
<configuration>
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
</sectionGroup>
</configSections>
<connectionStrings>
<add
name="MyElmahDatabase"
providerName="System.Data.SqlClient"
connectionString="Server=tcp:myServer.database.windows.net,1433;Database=myDB;User ID=user#myServer;Password=password;Trusted_Connection=False;Encrypt=True;Connection Timeout=30" />
</connectionStrings>
<elmah>
<security allowRemoteAccess="1" />
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="MyElmahDatabase" />
</elmah>
</configuration>
There are a couple of problems here:
There is no way for me to update or vary whether remote access is enabled between Service Configurations.
There is no way for me to update or vary the ELMAH connection string between Service Configurations.
This is because the web.config is packaged as is into the .cspkg file and ELMAH will not look at the Service Configuration settings (which are the only way I can vary configuration settings between Service Configurations).
I can think of many other examples where this is a problem...
Any data access frameworks that look directly at the connection strings section.
Any custom configuration settings I need to create.
...to name just two.
Am I missing something or is this a significant gap in the configuration management offered by Windows Azure?
EDIT
From the answer and comments below, it looks like this is something that is not well supported. I think that managing multiple solution build configurations to support different configuration profiles is a very weak solution. I should not have to rebuild the solution for each configuration profile I need (there will likely be quite a few). Compilation is not equal to configuration.
I was wondering if there was a way to modify the .cspkg file as it is just a zip file. According to this documentation you can on Linux.
I've looked at the manifest in the .cspkg file and it looks like this:
<PackageManifest version="2">
<Encryption keytype="1" />
<Contents hashtype="1">
<Item name="MyApp.Web.UI_<GUID>.cssx" hash="AED69299C5F89E060876BC16BD3D6DE5130F6E62FFD2B752BAF293435339B7E2" uri="/MyApp.Web.UI_<GUID>.cssx" />
<Item name="MyApp.Web.Services_<GUID>.cssx" hash="7AC81AFF642E4345173C8470C32A41118A4E3CFD4185B82D0ADA44B71057192D" uri="/MyApp.Web.Services_<GUID>.cssx" />
<Item name="SMPackage_<GUID>.csmx" hash="B5E6B83B62AF64C7C11CAC1A394ABBF15D7DB7667A773C5284CE5BE95C5834E9" uri="/SMPackage_<GUID>.csmx" />
<Item name="SDPackage_<GUID>.csdx" hash="F34B7C02A551D82BAD96881E2DA9447D0014D49B47CCB3840475BDC575234A7D" uri="/SDPackage_<GUID>.csdx" />
<Item name="NamedStreamPackage_<GUID>.csnsx" hash="FA2B5829FF5D9B2D69DCDDB0E5BDEE6B8B0BC09FFBF37DAEEE41CF3F3F4D0132" uri="/NamedStreamPackage_<GUID>.csnsx" />
</Contents>
<NamedStreams>
<Stream name="RequiredFeatures/MyApp.Web.Services/1.0" />
<Stream name="RequiredFeatures/MyApp.Web.UI/1.0" />
<Stream name="SupportData/MyApp.Web.Services/1.0" />
<Stream name="SupportData/MyApp.Web.UI/1.0" />
</NamedStreams>
</PackageManifest>
Unfortunately, if I re-compute the hash of the unchanged "MyApp.Web.UI_.cssx" file, my hash is different from the one in the manifest.
Hash from manifest: AED69299C5F89E060876BC16BD3D6DE5130F6E62FFD2B752BAF293435339B7E2
My calculated hash: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
Note that I have not yet changed the file, so the hash should be the same.
This suggests I'm calculating it wrong. My method was as follows:
class Program
{
static void Main(string[] args)
{
using (FileStream fs = new FileStream(args[0], FileMode.Open))
{
ComputeHash(new SHA256Managed(), fs);
}
}
private static void ComputeHash(HashAlgorithm hashAlgorithm, Stream stream)
{
byte[] hash = hashAlgorithm.ComputeHash(stream);
string hashString = BitConverter.ToString(hash);
Console.WriteLine(hashString.Replace("-", string.Empty));
Console.WriteLine();
}
}
The documentation link above, suggests it is straightforward to re-calculate the hash (on Linux anyway).
Does anyone know how to re-compute the hashes?
Passing a Stream to ComputeHash() ends up with a different hash as compared to using the byte[] overload. I don't know why.
Try something like:
private static void ComputeHash(HashAlgorithm hashAlgorithm, Stream stream)
{
BinaryReader reader = new BinaryReader(stream)
byte[] hash = hashAlgorithm.ComputeHash( reader.ReadBytes( (int)stream.Length ) );
string hashString = BitConverter.ToString(hash);
Console.WriteLine(hashString.Replace("-", string.Empty));
Console.WriteLine();
}
This will give you the hash you're after.
As you've probably already discovered, on linux you can get the digest with
openssl dgst -sha256 /path/to/file
I you have items in your web.config that you want to change depending on how it's being built, there is a solution that is outside of Azure that you can use. You can use Web.config transforms. These transforms are tied to your build configuration not your service configuration, but your service configurations a likely closely tied to your build configurations anyway (...Local.csfg -> Debug, ...Cloud.csfg -> Release). If the default build configurations don't work for you, just create the ones you need.
If you want to use different service definitions per service configuration, then it's not supported by the UI, but you can mess around with the build process to make it work

BUG: IIS7 managed requests

(I don't know whether should I also post this question to ServerFault, since it's about IIS configuration?)
In IIS7 we can tell a module to run for managed content (thus speeding up static content serving) by:
<modules>
...
<add name="WhateverName"
type="WhateverType"
preCondition="managedHandler"
...
</modules>
But. This works fine and dandy as long as there's also a file name (with extension) in the requested URL. If it's omitted it IIS7 will think you want static content and managed modules won't run.
http://localhost/ <-- this one will skip managed handlers
http://localhost/default.aspx <-- this one will run them
If I manually set IIS7 default document, so the first one is default.aspx, I can see no difference there's no difference. To me this looks, walks and sounds like a bug. And it is a bug! Why? Because when I request for the first one, it is a managed request, isn't it. Of course it is. But IIS7 treats it as a static request. So? It's a bug. This request should be treated as managed.
How can I convince IIS7 to run managed handlers for URL requests without file names inside?
Help with thinking
Let me help you a bit with thinking: If I'd reorder system.webServer/handlers, I'm sure could solve this. Before the last StaticFile handler that points to StaticFileModule, DefaultDocumentModule and DirectoryBrowsingModule I should be running integrated asp.net handler on Directory requests. Or write my own handler, that would append default document to any directory request. I'm pretty sure one of these should solve it. But how would I have to configure/develop it?
The problem is in request-processing order. IIS7 processes requests in order specified by Handlers configuration element of IIS. By default Handlers element of the IIS configuration contains
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
at the end of the handlers. Therefore all request that not match any previously specified handler, will be processed by this handler (including folder request too).
You can remove all default handlers by using clear element in handlers configuration and specify your own request processing order.
I recommend to copy default IIS handlers configuration (C:\Windows\System32\inetsrv\config\applicationHost.config) to your web config without StaticFile handler at the end.
Then you should add specific static content handler for each static content type (jpg, gif, js, css).
<add name="StaticFile-swf" path="*.swf" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFile-png" path="*.png" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFile-gif" path="*.gif" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFile-jpg" path="*.jpg" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFile-css" path="*.css" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFile-js" path="*.js" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
and manged handler (PageHandlerFactory) for folder requests after that.
<add name="PageHandlerFactory-Folders" path="*" verb="*" type="System.Web.UI.PageHandlerFactory" modules="ManagedPipelineHandler" resourceType="Unspecified" requireAccess="Read" allowPathInfo="false" preCondition="integratedMode" />
At the end you should also add StaticFile handler.
Here is an example.
Removing preCondition="managedHandler" or adding <modules runAllManagedModulesForAllRequests="true"> should do it. The "Preconditions" section of this page has more information.
You can use a wild card script mapping, but it's inefficient to use the managed handler to handle all requests. The static handler is much more efficient when it is appropriate.

How to send email in HTML format with Microsoft Enterprise Library?

I know how to send mails using the Microsoft Enterprise Library 2.0 using a text formatter. But these emails are always in plain text. Is there any way with entlib 2.0 to send these mails in HTML format?
Well that is funny, I am now writing my own answer.
What I did was use the source code of entlib.
Within
Microsoft.Practices.EnterpriseLibrary.Logging and
Microsoft.Practices.EnterpriseLibrary.Logging.TraceListenerData
I found the classes that I needed.
Copy EmailMessage.cs to EmailMessageHTML.cs
Copy EmailTraceListener.cs to EmailHTMLTraceListener.cs
Copy EmailTraceListenerData.cs to EmailHTMLTraceListenerData.cs
Put these classes in your own new Library Project.
Within EmailMessageHTML change all constructors to match the new classname and than ADD following line to the method:
protected MailMessage CreateMailMessage()
{
.....
message.IsBodyHtml = true;
.....
return message;
}
After that, I had to use this new EmailMessageHTML class in EmailHTMLTraceListener (change EmailMessage to EmailMessageHTML) and also use this EmailHTMLTraceListener in the new EmailHTMLTraceListenerData.cs file.
Compile this new project and than use this in your config as follows (example)
<loggingConfiguration
name="Logging Application Block"
tracingEnabled="true"
defaultCategory=""
logWarningsWhenNoCategoriesMatch="true">
<listeners>
<add toAddress="your#emailgoes.here"
fromAddress="yourserveraddress#goes.here"
subjectLineStarter=""
subjectLineEnder="My HTMLemailLogger"
smtpServer="localhost" smtpPort="25"
formatter="Text Formatter"
listenerDataType="MYLibrary.HTMLEmailLogger.EmailHTMLTraceListenerData,
MYLibrary.HTMLEmailLogger, Version=2.0.0.0,
Culture=neutral,
PublicKeyToken=null"
traceOutputOptions="None"
type="MYLibrary.HTMLEmailLogger.EmailHTMLTraceListener,
MYLibrary.HTMLEmailLogger,
Version=2.0.0.0,
Culture=neutral,
PublicKeyToken=null"
name="EmailHTML TraceListener"/>
</listeners>
</loggingConfiguration>
and add a valid category to log this to of course:
<add switchValue="All" name="OutOfBalanceBooking">
<listeners>
<add name="Database Trace Listener"/>
<add name="EmailHTML TraceListener"/>
</listeners>
</add>
Of course you need some HTML document to than log with EntLib. I leave that as an exercise for the reader.
And indeed! I get a nice HTML email now for every outofbalance booking that customers make on the site...