hangfire database not created after install - hangfire

I installed the hangfire with Nuget.
PM> Install-Package Hangfire
Then updated the OWIN Startup class with the following lines:
public void Configuration(IAppBuilder app)
{
GlobalConfiguration.Configuration.UseSqlServerStorage("MySqlConnection");
app.UseHangfireDashboard();
app.UseHangfireServer();
}
I named the connection string name on the web.config as the name of the connectionString In UseSqlServerStorage.
web.config:
<connectionStrings>
<add name="MyEntities" connectionString="metadata=res://*/CRMModelContext.csdl|res://*/CRMModelContext.ssdl|res://*/CRMModelContext.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=xxx;persist security info=True;user id=sa;password=123;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
<add name="MySqlConnection" connectionString="User ID=sa;Initial Catalog=xxx;Password=123;Integrated Security=False;Data Source=." />
SQL Server 2008 R2 is installed on the system but The database for the hangfire is not in it.
Finally, when I run the program, the error below.
My Job:
BackgroundJob.Enqueue<Receiver>(x=>x.EmailReceiving());
RecurringJob.AddOrUpdate<Receiver>(x => x.EmailReceiving(), Cron.MinuteInterval(15));
error:
JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.

I had struggled to find the right solution online, then after asking around, I realized that I should create the datatable on the server by myself, then the tables will be created by hangfire after the application started.
Basically, there are 3 main lines of code that I put in my application to make the hangfire works:(.netcore web application) (in the startup.cs)
public void ConfigureServices(IServiceCollection services)
{
......
string connectionString = "getYourConnectionStringHere";
services.AddHangfire(x => x.UseSqlServerStorage(connectionString));
services.AddHangfireServer();
......
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
....
app.UseHangfireDashboard("/hangfire"); //this is to set the url for hangfire, e.g. localhost://xxxx/hangfire
...
}

GlobalConfiguration.Configuration.UseSqlServerStorage("MySqlConnection"); is using MySqlConnection as a connection string, not the value of MySqlConnection!
Are you using MsSql Server or MySql Server?
Try :
GlobalConfiguration.Configuration.UseSqlServerStorage(ConfigurationManager.ConnectionStrings["MySqlConnection"].ConnectionString);

Related

Entity Framework ConnectionString Not Working

From as far as I can tell all of the questions that relate to this have not solved my issue.
I have an sql database hosted by Azure. Super simple, I want to connect it to my ASP.Net MVC app using Entity Framework.
Data Model has been added and edmx file is present,
Connection string
<connectionStrings><add name="MyDatabase" connectionString="...serverinfo"
providerName="System.Data.EntityClient" /></connectionStrings>
I go to my IdentityModels.cs and change the following
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("MyDatabase", throwIfV1Schema: false)
{
}
When i go to register a user in hopes that the users information will be added to my Azure database i get the following; "The entity type ApplicationUser is not part of the model for the current context."
I am kind of at my end on this. If someone can point me to documentation to build and applicaiton based upon a previously created database that I can follow or know what I am missing please let me know. Thank you
Edit your Connection String and Modify your code as Follow -
<connectionStrings>
<add name="MyDatabasedbEntitiesapplication" providerName="System.Data.SqlClient" connectionString="database and username password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" />
<add name="MyDatabasedbEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=yourdatasource,1433;initial catalog=yourdbname;user id=username;password=***;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
Modify the code:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("MyDatabase", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Modify AutomaticMigrationsEnabled = true; in Configuration class under Migrations folder.

Asp.Net core dbcontext issue

I am creating Asp.net core application and trying to connect to the database. I am getting an error at the following line of code in ConfigureServices method in the startup.cs file. The error that I am getting is the value cannot be null. It seems like it cant find the CustomerOrderEntities key in the web.config file. Not sure what the problem is
services.AddDbContext<CustomerOrderEntities>(options =>
options.UseSqlServer(Configuration.GetConnectionString("CustomerOrderEntities")));
Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CustomerOrderEntities>(options =>
options.UseSqlServer(Configuration.GetConnectionString("CustomerOrderEntities")));
AutoMapperConfiguration.Configure();
// Create the container builder.
var builder = new ContainerBuilder();
// Register dependencies, populate the services from
// the collection, and build the container. If you want
// to dispose of the container at the end of the app,
// be sure to keep a reference to it as a property or field.
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
builder.RegisterType<DbFactory>().As<IDbFactory>();
builder.RegisterType<CustomerRepository>().As<ICustomerRepository>();
builder.RegisterType<ProductRepository>().As<IProductRepository>();
builder.RegisterType<OrderRepository>().As<IOrderRepository>();
builder.Populate(services);
this.ApplicationContainer = builder.Build();
// Create the IServiceProvider based on the container.
return new AutofacServiceProvider(this.ApplicationContainer);
}
Web.Config
<connectionStrings>
<add name="CustomerOrderEntities" connectionString="metadata=res://*/EF.CustomerOrderContext.csdl|res://*/EF.CustomerOrderContext.ssdl|res://*/EF.CustomerOrderContext.msl;provider=System.Data.SqlClient;provider connection string="data source=test-PC\MSSQLSERVER2014;initial catalog=CodeFirstTest;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
Connection string in ASP.NET Core is defined in appsettings.json, for example:
"ConnectionStrings": {
"CustomerOrderEntities": "Server=(localdb)\\mssqllocaldb;Database=aspnet-a3e892a5-6a9c-4090-bc79-fe8c79e1eb26;Trusted_Connection=True;MultipleActiveResultSets=true"
},
In your case name of connecting string is CustomerOrderEntities, you get null, probably it's not there, check you appsettings.json.
Your connectionstring in Appsettings.json is definitely missing. You cannot set connection string in web.config in Asp.net core whether you are targeting full .net framework or .net core. Alternative you type the connection string value in services.AddDbContext(options =>
options.UseSqlServer("Your Connectionstring"));
for more information check here;
https://learn.microsoft.com/en-us/ef/core/

Package and publish Azure Cloud Service with unique Sql Azure connectionStrings

I have a .NET Web solution with an Azure Cloud Service project and a single webrole. I deploy it to the East coast West coast data/compute centers for failover purposes and have been asked to automate the deployment using Powershell MSBuild and Jenkins.
The problem is i need to change the Sql Azure database connectionString in the Web.config prior to packaging and publishing to each deployment. Seems simple enough.
I understand that the webrole properties Settings tab allows you to add custom configuration properties to each deployment with a type of either "string" or "Connection String" but it looks like the "Connection String" option applies to only Blob, Table or Queue storage. If I use the "String" and give it an Sql Azure connection string type it writes it out as an key/value pair and Entity Framework and the Membership Provider do not find it.
Is there a way to add a per-deployment connection string setting that points to Sql Azure?
Thanks,
David
Erick's solution is completely valid and I found an additional way to solve the problem so I thought I'd come back and put it up here since I had such trouble finding an answer.
The trick is getting the Entity Framework and any providers like asp.net Membership/profile/session etc... to read the connection string directly from the Azure service configuration rather than the sites web.config file.
For the providers I was able to create classes that inherit the System.Web.Providers.DefaultMembershipProvider class and override the Initialize() method where I then used a helper class I wrote to retrieve the connection string using the RoleEnvironment.GetConfigurationSettingValue(settingName); call, which reads from the Azure service config.
I then tell the Membership provider to use my class rather than the DefaultMembershipProvider. Here is the code:
Web.config:
<membership defaultProvider="AzureMembershipProvider">
<providers>
<add name="AzureMembershipProvider" type="clientspace.ServiceConfig.AzureMembershipProvider" connectionStringName="ClientspaceDbContext" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
Note the custom provider "AzuremembershipProvider"
AzuremembershipProvider class:
public class AzureMembershipProvider : System.Web.Providers.DefaultMembershipProvider
{
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
string connectionStringName = config["connectionStringName"];
AzureProvidersHelper.UpdateConnectionString(connectionStringName, AzureProvidersHelper.GetRoleEnvironmentSetting(connectionStringName),
AzureProvidersHelper.GetRoleEnvironmentSetting(connectionStringName + "ProviderName"));
base.Initialize(name, config);
}
}
And here's the helper class AzureProvidersHelper.cs:
public static class AzureProvidersHelper
{
internal static string GetRoleEnvironmentSetting(string settingName)
{
try
{
return RoleEnvironment.GetConfigurationSettingValue(settingName);
}
catch
{
throw new ConfigurationErrorsException(String.Format("Unable to find setting in ServiceConfiguration.cscfg: {0}", settingName));
}
}
private static void SetConnectionStringsReadOnly(bool isReadOnly)
{
var fieldInfo = typeof (ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
if (
fieldInfo != null)
fieldInfo.SetValue(ConfigurationManager.ConnectionStrings, isReadOnly);
}
private static readonly object ConnectionStringLock = new object();
internal static void UpdateConnectionString(string name, string connectionString, string providerName)
{
SetConnectionStringsReadOnly(false);
lock (ConnectionStringLock)
{
ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings["name"];
if (connectionStringSettings != null)
{
connectionStringSettings.ConnectionString = connectionString;
connectionStringSettings.ProviderName = providerName;
}
else
{
ConfigurationManager.ConnectionStrings.Add(new ConnectionStringSettings(name, connectionString, providerName));
}
}
SetConnectionStringsReadOnly(true);
}
}
The key here is that the RoleEnvironment.GetConfigurationSettingValue reads from the Azure service configuration and not the web.config.
For the Entity Framework that does not specify a provider I had to add this call to the Global.asax once again using the GetRoleEnvironmentSetting() method from the helper class:
var connString = AzureProvidersHelper.GetRoleEnvironmentSetting("ClientspaceDbContext");
Database.DefaultConnectionFactory = new SqlConnectionFactory(connString);
The nice thing about this solution is that you do not end up having to deal with the Azure role onstart event.
Enjoy
dnash
David,
A good option is to use the Azure configurations. If you right click on the Azure project, you can add an additional configuration. Put your connection string(s) in the correct configuration (e.g., ServiceConfiguration.WestCoast.cscfg, ServiceConfiguration.EastCoast.cscfg, etc).
In your build script, pass the TargetProfile property to MSBuild with the name of the configuration, and those settings will be built into the final cscfg.
Let me know if you run into any problems. I did the approach, and it took a few tries to get it working right. Some details that might help.
Erick

Custom Authorization & Role in MVC 4 not working

I need to implement a Single Sign on where a Com+ component should be called to authenticate the user & provide the roles. In short, I need to bypass the default mechanism in MVC 4 where it tries to access the aspnetdb database. So I started with a new MVC4 internet project and added the following code.
In Global.asax
public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
{
bool retval = CreateUserObject("John", "pwd");
}
private bool CreateUserObject(string userName, string password)
{
string[] currentUserRoles = { "Admin", "User" };
GenericPrincipal userPrincipal = new GenericPrincipal(new GenericIdentity(userName), currentUserRoles);
HttpContext.Current.User = userPrincipal;
//Thread.CurrentPrincipal = userPrincipal;
return true;
}
Within the HomeController.cs, I added the [Authorize] attribute for the "About" action as below and it works as expected
[Authorize]
public ActionResult About()
However if I modify the [Authorize] attribute to permit only "Admin" role as below I get a runtime error (at the bottom). Is there a way around this to use my own collection of roles for the logged in user, instead of querying the database? I also need to do something similar to the user Profile as well (i.e, instead of database, I should populate the values from the Com+ application.
[Authorize(Roles = "Admin")]
public ActionResult About()
Server Error in '/' Application.
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)
Maybe you need to create a Custom RoleProvider, like this:
namespace DemoApp.Providers
{
public class MyCustomRoleProvider : System.Web.Security.SqlRoleProvider
{
public override string[] GetRolesForUser(string username)
{
string[] currentUserRoles = { "Admin", "User" };
return currentUserRoles;
}
}
}
And in the web.config of the application, change the default role provider:
<system.web>
<roleManager enabled="true" defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="DemoApp.Providers.MyCustomRoleProvider, DemoApp"/>
</providers>
</roleManager>
<system.web>

S#arp Lite - NHibernate Initializer not finding named connection string

I am attempting to use S#arp Lite. I have followed the instructions here - https://github.com/codai/Sharp-Lite/blob/master/README.txt
When I first attempt to run the MappingIntegrationTests in NUnit, I receive the following errors:
MySolution.Tests.NHibernateProvider.MappingIntegrationTests.CanConfirmDatabaseMatchesMappings:
SetUp : NHibernate.HibernateException : Could not find named connection string MySolutionConnectionString
MySolution.Tests.NHibernateProvider.MappingIntegrationTests.CanConfirmDatabaseMatchesMappings:
SetUp : NHibernate.HibernateException : Could not find named connection string MySolutionConnectionString
NUnit indicates that the above errors are coming from the second line of the SetUp method in MappingIntegrationTests.
[SetUp]
public virtual void SetUp() {
_configuration = NHibernateInitializer.Initialize();
_sessionFactory = _configuration.BuildSessionFactory();
}
The Initialize method of my NHibernateInitializer class,
public static Configuration Initialize() {
Configuration configuration = new Configuration();
configuration.Proxy(p => p.ProxyFactoryFactory<DefaultProxyFactoryFactory>())
.DataBaseIntegration(db => {
db.ConnectionStringName = "MySolutionConnectionString";
db.Dialect<MsSql2008Dialect>();
})
.AddAssembly(typeof(ActionConfirmation<>).Assembly)
.CurrentSessionContext<LazySessionContext>();
ConventionModelMapper mapper = new ConventionModelMapper();
mapper.WithConventions(configuration);
return configuration;
}
And the App.Config file from MySolution.Tests project,
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MySolutionConnectionString" connectionString="data source=.\SQLEXPRESS;Initial Catalog=MySolutionDB-DEV;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
</ connectionStrings>
</configuration>
I don't understand why the NUnit test runner is failing with the message Could not find named connection string MySolutionConnectionString. According to James Kovacs' blog post on Loquacious Configuration, this seems like this should work no problem -
"Setting db.ConnectionStringName causes NHibernate to read the connection string from the config section of the [App|Web].config."
MySolution.Tests is a dll but App.configs are only read for the starting .exe file which is the NUnit testrunner.