Hangfire 1.5.3 System.MissingMethodException on all our jobs - c#

We just updated hangfire from 1.3.4 to 1.5.3.
Our startup has changed from this:
private static void DoHangfire(IAppBuilder app)
{
var options = new BackgroundJobServerOptions
{
// Set thread count to 1
WorkerCount = 1
};
app.UseHangfire(config =>
{
config.UseSqlServerStorage(ConfigurationManager.ConnectionStrings["JobsDB"].ConnectionString);
config.UseAuthorizationFilters(new HangfireDashboardAuthorizationFilter());
config.UseServer(options);
});
// Set retries to zero
GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });
JobActivator.Current = new WindsorJobActivator(Container.Kernel);
}
to this:
private static void DoHangfire(IAppBuilder app)
{
var options = new BackgroundJobServerOptions
{
// Set thread count to 1
WorkerCount = 1
};
GlobalConfiguration.Configuration.UseSqlServerStorage(
ConfigurationManager.ConnectionStrings["JobsDB"].ConnectionString);
app.UseHangfireDashboard("/hangfire", new DashboardOptions()
{
AuthorizationFilters = new List<IAuthorizationFilter>
{
new HangfireDashboardAuthorizationFilter()
}
});
app.UseHangfireServer(options);
// Set retries to zero
GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });
JobActivator.Current = new WindsorJobActivator(Container.Kernel);
}
Now all our jobs (we have 4 different kinds of jobs) fail immediately with this error:
System.MissingMethodException: No parameterless constructor defined
for this object. at
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean
publicOnly, Boolean noCheck, Boolean& canBeCached,
RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean
skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly,
Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic) at
System.Activator.CreateInstance(Type type) at
Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(Type type) at
Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext
context) at
Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass3.b__0()
at
Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter
filter, PerformingContext preContext, Func1 continuation) at
Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext
context, IEnumerable1 filters) at
Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context,
IStorageConnection connection, String jobId)

Well the problem had to do with some magic in how the new version of Hangfire interacted with the Hangfire.Windsor package, which simply provides a custom JobActivator with a windsor container for service location.
By moving the
JobActivator.Current = new WindsorJobActivator(Container.Kernel);
above the call to app.UseHangfireServer() we were able to uncover the real exception message, which was a Castle.MicroKernel.ComponentNotFoundException informing us that it couldn't wire in the dependency containing the method we wanted hangfire to run.
Suffice to say, in 1.3.4, to run a job you can do this:
BackgroundJob.Enqueue(() => thingWhichDoesStuff.DoStuff());
where thingWhichDoesStuff is injected into the containing class and the hangfire.windsor JobActivator is just magically able to resolve to the type.
However in 1.5.3 this magic resolution no longer happens, so you must explicitly tell the JobActivator the interface of the type containing the method you want hangfire to run:
BackgroundJob.Enqueue<IDoStuff>(x => x.DoStuff());
This causes all our jobs to start working again.

Related

Error creating new outlook email from the server

I have a function that can create a new email in outlook and it works fine when running on my local machine. However, when deployed to the server i get the error shown below.
This is what it looks like when I run the code on my local machine:
Link. Is it possible to make this code run on the server and generate emails for users?
Error:
System.Runtime.InteropServices.COMException (0x80080005): Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)). at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType) at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(RuntimeType serverType) at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(RuntimeType serverType, Object[] props, Boolean bNewObj) at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at MyProjectName.btnEmailEstimate_Click(Object sender, EventArgs e) in D:\My\Project\location\MyProjectName.ascx.cs:line 9833
Here is my code:
protected void btnEmailEstimate_Click(object sender, EventArgs e)
{
try
{
List<string> lstAllRecipients = new List<string>();
//Below is hardcoded - can be replaced with db data
lstAllRecipients.Add("test1#testmail.com");
lstAllRecipients.Add("test2#testmail.com");
Outlook.Application outlookApp = new Outlook.Application();
Outlook._MailItem oMailItem = (Outlook._MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
Outlook.Inspector oInspector = oMailItem.GetInspector;
// Recipient
Outlook.Recipients oRecips = (Outlook.Recipients)oMailItem.Recipients;
foreach (String recipient in lstAllRecipients)
{
Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(recipient);
oRecip.Resolve();
}
//Add CC
Outlook.Recipient oCCRecip = oRecips.Add("testCC#testmail.com");
oCCRecip.Type = (int)Outlook.OlMailRecipientType.olCC;
oCCRecip.Resolve();
//Add Subject
oMailItem.Subject = "Test Mail";
// body, bcc etc...
oMailItem.Body = "Email body content here \nThis is a new line.";
//Display the mailbox
oMailItem.Display(true);
var time = DateTime.Now;
tbLast_email_update.Text = time.ToString();
}
catch (Exception objEx)
{
Response.Write(objEx.ToString());
}
}

Can't Enqueue my Job in hangfire server

I am working on enqueue jobs using hangfire in my application.
my enqueue job statement is given below,
string jobId = BackgroundJob.Enqueue(() =>
strategy.get(typeof(_service.Engine.Summary), cpdata));
when this will enqueue my job successfully but got the error message in State table like this,
"FailedAt": "2018-03-21T13:14:46.0172303Z", "ExceptionType":
"System.MissingMethodException", "ExceptionMessage": "No
parameterless constructor defined for this object.",
"ExceptionDetails": "System.MissingMethodException: No parameterless
constructor defined for this object.\r\n at
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean
publicOnly, Boolean noCheck, Boolean& canBeCached,
RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)\r\n
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean
skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)\r\n at
System.Activator.CreateInstance(Type type, Boolean nonPublic)\r\n at
System.Activator.CreateInstance(Type type)\r\n at
Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(Type type)\r\n
at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext
context)\r\n at
Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.b__0()\r\n
at
Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter
filter, PerformingContext preContext, Func 1 continuation)\r\n at
Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext
context, IEnumerable`1 filters)\r\n at
Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext
context)\r\n at
Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context,
IStorageConnection connection, String jobId)"
Is this DI issue that creating this type of error?
i used calling method in Enqueue using the reference of this link
Factory method with DI and IOC
For Example,
var strategy = new CarStrategy(new ICarFactory[] {
new Car1Factory(dep1, dep2, dep3),
new Car2Factory(dep4, dep5, dep6),
new Car3Factory(dep7, dep8, dep9)
});
My Code is Like this,
var strategy = new Strategy(new ICP[] {
new _Services.Engine.Detail.Detail(),
new _1Services.Engine.Summary.Summary(),
});
var CP = PrepareCPModelForEngine(c);
string jobId = BackgroundJob.Enqueue(() =>
strategy.get(typeof(_Services.Engine.Summary.Summary), cp));

Error while creating recurring job using Hangfire

I'm trying to use Hangfire in my application to fetch( from external APIs) currency conversion rates on a daily basis and insert in application database.
Successfully configured ( think so ) and the Hangfire Tables are created in the DB and the Job table is having entries but the Job is not successfully executed and while checking the State Table it shows failed and have an error message like
{"FailedAt":"2017-10-12T07:55:00.3075439Z",
"ExceptionType":"System.MissingMethodException",
"ExceptionMessage":"Cannot create an instance of an interface.",
"ExceptionDetails":"System.MissingMethodException: Cannot create an instance of an interface.\r\n
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)\r\n
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)\r\n
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)\r\n
at System.Activator.CreateInstance(Type type, Boolean nonPublic)\r\n at System.Activator.CreateInstance(Type type)\r\n at Hangfire.JobActivator.ActivateJob(Type jobType)\r\n
at Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(Type type)\r\n at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)\r\n
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.<PerformJobWithFilters>b__0()\r\n
at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)\r\n
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_1.<PerformJobWithFilters>b__2()\r\n
at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)\r\n
at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)\r\n
at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)"}
Code used :
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
GlobalConfiguration.Configuration.UseSqlServerStorage("ERPContext");
RecurringJob.AddOrUpdate<IAPIRequest>(x => x.ProcessCurrencyConversion(), Cron.MinuteInterval(1));
app.UseHangfireDashboard();
app.UseHangfireServer();
}
}
Interface and Class which has the Method to executed
public interface IAPIRequest
{
void ProcessCurrencyConversion();
}
public class APIRequest : IAPIRequest
{
public void ProcessCurrencyConversion()
{
WebClient client = new WebClient();
string urlPattern = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22USDKWD,EURKWD,GBPKWD,AEDKWD,ZARKWD%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
var jsonResult = client.DownloadString(urlPattern);
dynamic results = JsonConvert.DeserializeObject<dynamic>(jsonResult);
var rates = results.rate;
List<CurrencyJSON> currencies = new List<CurrencyJSON>();
using (var db = new ERPContext())
{
foreach (var rate in rates)
{
var currencyJson = new CurrencyJSON();//POCO
currencyJson.Bid = rate.Bid;
currencyJson.Name = rate.Name;
currencies.Add(currencyJson);
}
db.Configuration.AutoDetectChangesEnabled = false;
db.Configuration.ValidateOnSaveEnabled = false;
db.CurrencyJson.ToList().AddRange(currencies);
db.SaveChanges();
}
}
}
What am I doing wrong?
Appreciate any help , Thanks in advance .
Have already checked similar question posted here but didn't help .
As #Diado pointed out in the comments, HangFire needs a IoC if using an Interface as there is no default support. Or you can use the Class directly instead of an interface.
https://github.com/devmondo/HangFire.SimpleInjector is one of the IoC injector which I used .

Creating Windows service to send automated email through outlook com interop

I am trying to develop an application that sends automated emails through outlook and interop services and getting the following exception. below is the code with exception.
try
{
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem mailItem = (Outlook.MailItem)app.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.Subject = "Details of Subject";
mailItem.To = "example#gmail.com";
mailItem.Body = "Automated email testing"
// mailItem.Attachments.Add(logPath);//logPath is a string holding path to the log.txt file
mailItem.Importance = Outlook.OlImportance.olImportanceHigh;
mailItem.Display(false);
mailItem.Send();
}
catch (Exception ex)
{
WriteErrorLog("\n");
WriteErrorLog(ex.Message);
WriteErrorLog(ex.StackTrace);
}
And its throwing an exception :
System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType) at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(RuntimeType serverType) at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(RuntimeType serverType, Object[] props, Boolean bNewObj)
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at WServiceMixInOne.ConnectionLogs.MainClass() in C:\Users\admin\documents\visual studio 2017\Projects\WServiceMixInOne\WServiceMixInOne\ConnectionLogs.cs:line 120
Line 120 is the 1st line app = new Microsoft.Office.Interop.Outlook.Application();
Try closing outlook from background process. And then execute your code.

Entity Framework 6 migrations with MVC 6 RC 1

We have a EF 6 Dbcontext and migrations in the separate class library project (data layer), rather than in the main mvc 6 project.
However, when we are trying to call this on the first run of the project
context.Database.Initialize(false);
We get very strange error message
System.IO.FileNotFoundException Could not find file
'MyProject.Data.resources'.
Stack Trace:
at System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(String name, CultureInfo culture, Version version, Boolean throwOnFileNotFound, StackCrawlMark& stackMark)
at System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(CultureInfo lookForCulture, StackCrawlMark& stackMark)
at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
at System.Resources.ResourceManager.GetString(String name)
at System.Data.Entity.Migrations.DbMigrator.GetDefaultSchema(DbMigration migration)
at System.Data.Entity.Migrations.DbMigrator.<GetHistorySchemas>b__6(<>f__AnonymousType10<String, DbMigration> <>h__TransparentIdentifier4)
at System.Linq.Enumerable.<>c__DisplayClass7_0<TSource, TMiddle, TResult>.<CombineSelectors>b__0(TSource x)
at System.Linq.Enumerable.WhereSelectListIterator<TSource, TResult>.MoveNext()
at System.Linq.Enumerable.<ConcatIterator>d__58<TSource>.MoveNext()
at System.Linq.Enumerable.<ConcatIterator>d__58<TSource>.MoveNext()
at System.Linq.Enumerable.<DistinctIterator>d__63<TSource>.MoveNext()
at System.Linq.Buffer<TElement>..ctor(IEnumerable<TElement> source)
at System.Linq.Enumerable.<ReverseIterator>d__74<TSource>.MoveNext()
at System.Data.Entity.Migrations.History.HistoryRepository.QueryExists(String contextKey)
at System.Data.Entity.Migrations.History.HistoryRepository.Exists(String contextKey)
at System.Data.Entity.Migrations.History.HistoryRepository.<GetUpgradeOperations>d__16.MoveNext()
at System.Linq.Enumerable.Any<TSource>(IEnumerable<TSource> source)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update()
at System.Data.Entity.MigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration>.InitializeDatabase(TContext context)
at System.Data.Entity.Internal.InternalContext.<>c__DisplayClassf<TContext>.<CreateInitializationAction>b__e()
at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
at System.Data.Entity.Internal.RetryAction<TInput>.PerformAction(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action<InternalContext> action)
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
at System.Data.Entity.Internal.InternalContext.Initialize()
at System.Data.Entity.Database.Initialize(Boolean force)
at MyProject.Data.DbHelper.SetupDatabase() in E:\Projects\MyProject\src\MyProject.Data\DbHelper.cs:line 29
at MyProject.Business.Services.DatabaseService.SetupDatabase() in E:\Projects\MyProject\src\MyProject.Business\Services\DatabaseService.cs:line 17
at MyProject.Web.Startup.ConfigureServices(IServiceCollection services) in E:\Projects\MyProject\src\MyProject.Web\Startup.cs:line 61
That's very strange. It works when we are trying to set connection string in the Data project's App.config and run update-database from package manager console (but I believe that's because in that case it behaves like a separate project).
Anyone have a good solution to this problem?
P.S. The other issues are not answering to this, because it is a problem with accessing migration in csproj project from xproj project.
It's a knowned dnx issue. It's not a migration problem, but a problem about EF6 model in class libraries.
Answer is here : Entity Framework 7 error : "EntityFramework.Core.resources" is missing (7.0.0-rc1-final)
Add this to your Startup's Configure method :
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//...
var localizationOptions = new RequestLocalizationOptions()
{
SupportedCultures = new List<CultureInfo> { new CultureInfo("") },
SupportedUICultures = new List<CultureInfo> { new CultureInfo("") }
};
var invariantCulture = new RequestCulture(new CultureInfo(""), new CultureInfo(""));
app.UseRequestLocalization(localizationOptions, invariantCulture);
//...
}

Categories