I need to create a function that runs as a background service. I need this function to make an api call every 30 seconds to opentdb.com ..and save those questions, options and correct answers to the database.
I am making the project with .NET framework MVC. I did some research and all leads to [System.Timers.Timer and System.Threading.Timer.] and it I understood that TIA putting a timer in API is not smart so I also looked for hangfire. However I have
no idea how to implement this
In the example given, Hangfire is configured in the Startup.cs file.
If you don't have a Startup.cs file, you can right-click the project and select New Item, and then search for OWIN Startup Class to
create a Startup.cs file.
The example uses the EF framework and a custom Api is written for testing. You can
modify it according to your needs.
More details, you could refer to below code:
Startup.cs
public class Startup
{
private IEnumerable<IDisposable> GetHangfireServers()
{
GlobalConfiguration.Configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage("DailyWebAPIMVCDemoContext", new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
});
yield return new BackgroundJobServer();
}
public void Configuration(IAppBuilder app)
{
app.UseHangfireAspNet(GetHangfireServers);
app.UseHangfireDashboard();
}
}
DailyWebAPIMVCDemoContext
public class DailyWebAPIMVCDemoContext : DbContext
{
public DailyWebAPIMVCDemoContext()
: base("name=DailyWebAPIMVCDemoContext")
{
}
public virtual DbSet<Question> Questions { get; set; }
public virtual DbSet<Answer> Answers { get; set; }
}
Model
public class Question
{
[Key]
public int QuestionId { get; set; }
public string QuestionName { get; set; }
public string CreateTime { get; set; }
public ICollection<Answer> answers { get; set; }
}
public class Answer
{
[Key]
public int AnswerId { get; set; }
public string AnswerName { get; set; }
public string AnswerOption { get; set; }
public bool IsTrueAnswer { get; set; }
public string CreateTime { get; set; }
public int QuestionId { get; set; }
[ForeignKey("QuestionId")]
public Question question { get; set; }
}
QuestionController
public class QuestionController : ApiController
{
public Question Get()
{
Question question = new Question {
QuestionName = "test",
answers = new List<Answer> {
new Answer { AnswerName="answer1",AnswerOption="hello1",IsTrueAnswer=true},
new Answer { AnswerName="answer2",AnswerOption="hello2",IsTrueAnswer=false},
new Answer { AnswerName="answer3",AnswerOption="hello3",IsTrueAnswer=false},
new Answer { AnswerName="answer4",AnswerOption="hello4",IsTrueAnswer=false}
}
};
return question;
}
}
HomeController
public class HomeController : Controller
{
public DailyWebAPIMVCDemoContext db = new DailyWebAPIMVCDemoContext();
public ActionResult Index()
{
QuestionJob();
return View();
}
public static async Task GetQuestionAsync()
{
using (var client = new HttpClient())
{
var response = await client.GetAsync("https://localhost:44302/api/Question");
var question = new Question();
if (response.IsSuccessStatusCode)
{
question = await response.Content.ReadAsAsync<Question>();
}
if (question != null)
{
question.CreateTime = DateTime.Now.ToString();
using (var db = new DailyWebAPIMVCDemoContext())
{
db.Questions.Add(question);
if (question.answers != null)
{
question.answers.ToList().ForEach(a => { a.CreateTime = question.CreateTime; db.Answers.Add(a); });
}
db.SaveChanges();
}
}
}
}
public static void QuestionJob()
{
var manager = new RecurringJobManager();
manager.AddOrUpdate("1", Job.FromExpression(() => GetQuestionAsync()), "*/30 * * * * ?", TimeZoneInfo.Local);
}
}
Here is the result.
Best Regards,
YihuiSun
ASP.NET forums are moving to a new home on Microsoft Q&A, we encourage you to go to Microsoft Q&A for .NET for posting new questions and get involved today. Learn more >
In the example given, Hangfire is configured in the Startup.cs file.
If you don't have a Startup.cs file, you can right-click the project and select New Item, and then search for OWIN Startup Class to
create a Startup.cs file.
Member
2 Points
13 Posts
Creating an background API
Sep 13, 2020 05:56 PM|Lestat90|LINK
I need to create a function that runs as a background service. I need this function to make an api call every 30 seconds to opentdb.com ..and save those questions, options and correct answers to the database.
I am making the project with .NET framework MVC. I did some research and all leads to [System.Timers.Timer and System.Threading.Timer.] and it I understood that TIA putting a timer in API is not smart so I also looked for hangfire. However I have no idea how to implement this
TIA
Contributor
3040 Points
863 Posts
Re: Creating an background API
Sep 14, 2020 06:58 AM|YihuiSun|LINK
Hi Lestat90,
According to your needs, I wrote an example of using hangfire, you can refer to it.
More details, you could refer to below code:
Startup.cs
DailyWebAPIMVCDemoContext
public class DailyWebAPIMVCDemoContext : DbContext { public DailyWebAPIMVCDemoContext() : base("name=DailyWebAPIMVCDemoContext") { } public virtual DbSet<Question> Questions { get; set; } public virtual DbSet<Answer> Answers { get; set; } }
Model
QuestionController
HomeController
Here is the result.
Best Regards,
YihuiSun
Member
2 Points
13 Posts
Re: Creating an background API
Sep 15, 2020 01:32 PM|Lestat90|LINK
This all looks confusing but I will try to modify to save the json data in mysql evey 30 sec. thanks a lot man
Member
2 Points
13 Posts
Re: Creating an background API
Sep 16, 2020 07:50 PM|Lestat90|LINK
I did it but it throws this when i try to log in:
System.ArgumentException: 'Keyword not supported: 'data source'.'
after I changed the connection string in web.config , because prior to this error it was throwing : Keyword not supported: 'data source'. exception