Please note that I have a math library that performs calculations, and when I unit test the library the values returned are correct.
Then I call this library from a function in my Web API application:
private readonly ICalcContext _context;
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
private readonly MemoryCache _memCache = MemoryCache.Default;
public CalcRepository(ICalcContext context)
{
_context = context;
}
public async Task<double[]> GetCalculationAsync(string username, string password, int corporationId, double latitude,
double longitude, double depth, bool includeWellRuns = false)
{
double[] results = null;
Calculation calc = _context.Calculations.FirstOrDefault(e => e.CorporationId == corporationId);
if (calc == null) calc = new Calculation();
var user = _context.MyCalcs.FirstOrDefault(e => e.UserName == username);
if (user?.LicenseKey == password)
{
results = MyMathLibrary.MyCalculationFunction(latitude, longitude, depth, DateTime.Now.Day,
DateTime.Now.Month, DateTime.Now.Year, DateTime.Now.Year, calc.UseGeoid, calc.UseDecimalYear);
calc.Value1 = Convert.ToString(results[0]);
calc.Value2 = Convert.ToString(results[1]);
calc.CorporationId = corporationId;
if (String.IsNullOrEmpty(calc.Username)) calc.Username = username;
if (String.IsNullOrEmpty(calc.Password)) calc.Username = password;
_context.Calculations.AddOrUpdate(calc);
await SaveChangesAsync();
CacheHandling(calc);
}
return results;
}
private void CacheHandling(Calculation calc)
{
var res = _memCache.Get("calc");
if (res != null)
{
//This is to remove the MemoryCache - start
if (_memCache.Contains("calc"))
{
_memCache.Remove("calc");
}
}
else
{
_memCache.Add("calc", calc, DateTimeOffset.UtcNow.AddSeconds(30));
}
}
Here is my controller function:
[Route("{username}/{password}/{latitude}/{longitude}/{depth}/{corporationId}")]
public async Task<IHttpActionResult> Get(string username, double latitude,
double longitude, double depth, int corporationId)
{
try
{
var result = await _repository.GetCalculationAsync(username, password, corporationId, latitude, longitude, depth);
if (result == null) return NotFound();
// Mapping
// This centralizes all of the config
var mappedResult = _mapper.Map<IEnumerable<CalculationModel>>(result);
return Ok(mappedResult);
}
catch (Exception ex)
{
Logger.Error(ex);
// Be careful about returning exception here
return InternalServerError();
}
}
The problem is that every time I call the Web API function through the web browser client, the same values show up in my web browser.
Here is one sample input URL: http://localhost:6600/api/calculations/mycompany&mypassword&34.123478&-115.123478&2/
Then here is a second URL I send which should cause new values to show up in the web browser client, but doesn't for some reason:
http://localhost:6600/api/calculations/mycompany&mypassword&10.123478&-100.123478&2/
I have even tried clearing the cache, but if I run the function call with different input values it returns the same values to the web client.
The time it worked to give the new updated values is when I changed form using Chrome as the web browser client to using Firefox.
Here are some websites I have checked but am not sure how I can apply this to my situation:
How to clear MemoryCache in ASP.NET Core?
https://www.codeproject.com/Articles/1087902/Caching-in-Web-API
What is the difference between PreserveReferencesHandling and ReferenceLoopHandling in Json.Net?
How to reset serialization after each web api call : C#
So could anyone please explain why the WebAPI/web client are showing the same values, even when I clear the cache? Do I need to clear something in "IIS Express" somehow? What am I missing? This is basically the first Web API I have ever built. TIA.
UPDATE:
Thanks for the suggestions @Kenneth K.
This is what I see in Postman so it looks like the controller is being hit:
UPDATE 2:
Thanks for the suggestion, @Andrei Dragotoniu
Please note that I have now published the Web API to the IIS on the virtual machine. When I call it, I use this URL with the parameter names as you suggested and in Postman it appears to work:
Yes, of course I can use the headers to store the password once I get the basic functionality working. According to Postman, it appears to connect, but I've have changed the CalcController to add a new record every time it is called by changing to _context.Calculations.Add(calc)
, and even when I use Postman to execute the URL it doesn't appear to actually execute this _context.Calculations.Add(calc)
portion because I see no new records added to the database, so I'm not sure what to do next. Any ideas?
public async Task<double[]> GetCalculationAsync(string username, string password, int corporationId, double latitude,
double longitude, double depth, bool includeWellRuns = false)
{
double[] results = null;
try
{
var calc = new Calculation();
var user = _context.MyCalcs.FirstOrDefault(e => e.UserName == username);
if (user?.LicenseKey == password)
{
results = MyMathLibrary.MyCalculationFunction(latitude, longitude, depth, DateTime.Now.Day,
DateTime.Now.Month, DateTime.Now.Year, DateTime.Now.Year, calc.UseGeoid, calc.UseDecimalYear);
calc.Declination = Convert.ToString(results[0]);
calc.Inclination = Convert.ToString(results[1]);
calc.TotalField = Convert.ToString(results[2]);
calc.CorporationId = corporationId;
if (String.IsNullOrEmpty(calc.Username)) calc.Username = username;
if (String.IsNullOrEmpty(calc.Password)) calc.Password = password;
_context.Calculations.Add(calc);
await SaveChangesAsync();
//CacheHandling(calc);
}
}
catch (Exception ex)
{
Logger.Error(ex);
throw;
}
return results;
}