Wednesday, April 17, 2019

how to fix DateTime.parseExact exception in Windows Server 2019?

when I deployed the ETL that use the exact date format like MM/dd/yyyy to load the date from configuration setting section.

i got the following error from the application log

Application: DealerETL.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.FormatException
   at System.DateTime.ParseExact(System.String, System.String, System.IFormatProvider)
   at DealerETL.SciAzure.Utilities.DaxHelper..cctor()

Exception Info: System.TypeInitializationException
   at DealerETL.SciAzure.Utilities.DaxHelper.rangeOfDealers()
   at DealerETL.SciAzure.DealerService+<UpdateDealer>d__1.MoveNext()

Exception Info: System.AggregateException
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean)
   at System.Threading.Tasks.Task.Wait(Int32, System.Threading.CancellationToken)
   at DealerETL.Program.Main(System.String[])


it is working fine to "MM/dd/yyyy" in the local development.. however the exception will be thrown if we did not change it to "MM'/'dd'/'yyyy".




Thursday, April 11, 2019

how to use general approach on caching in Web Api Development?

it is quite simple and stupid to implement a straight forward caching..

first we will define a MemoryCache and AsyncLock

private static readonly MemoryCache cache = MemoryCache.Default;
private static readonly AsyncLock myAsyncLock = new AsyncLock();

second we will write the logic to utilize the cache from MemoryCache.

const string CacheKey = "MyCacheKey";
           var myCacheObjects = cache.Get(CacheKey) as Cache Object type;
 
           if (myCacheObjects == null)
           {
               using (await myAsyncLock.LockAsync())
               {
                  //your logic here to load the cache objects
                   
                 cache.Set(CacheKey, titles, new CacheItemPolicy() 
                 { AbsoluteExpiration = DateTimeOffset.Now.AddHours(12) });
               }
           }
         return myCacheObjects ;

if we have more objects to be cache in the project, then we will have code redudent issue. since cache logic need to copy everywhere. the maintainance will be an issue as well. since the logic had been copied everywhere

i copied the idea from this link after i google for a solution.

How to cache data in a MVC application

i just a modification so that it handle the async call on loading the data for  caching..

 
public class MemoryCacheService : ICacheService
{
    public async Task<T> GetOrSetAsync<T>(string cacheKey, Func<Task<T>> getItemCallback) 
      where T : class
    {
        T item = MemoryCache.Default.Get(cacheKey) as T;
        if (item == null)
        {
            item =await getItemCallback();
            MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddHours(12));
        }
        return item;
    }
}
 
interface ICacheService
{
     Task<T> GetOrSetAsync<T>(string cacheKey, Func<Task<T>> getItemCallback) 
        where T : class;
}

 how to use this caching service. please view the following snippet of code.

[Route("api/title")]
       public async Task<IList<Title>> GetMYTitles()
       {
           const string cacheKey = "WebApi-GetTitles";
           MemoryCacheService memoryCacheService = new MemoryCacheService();
           System.Func<Task<IList<Salution>>> myFunGetTitles =
                    async () => await GetTitlesAsync();
           return await memoryCacheService.GetOrSetAsync<IList<Salution>>
                 (cacheKey, myFunGetTitles);
 
       }
       private async Task<IList<Title>> GetTitlesAsync()
       {
           string url = "salutations";
           APIResult result = await InvokeAzureAPICall(url);
           IList<Salution> titles = (List<Title>)JsonConvert.DeserializeObject
              (result.apiResponse, typeof(List<Title>));
           return titles;
       }
 


 if you like it, feel free to take it and your feed back will be greatly appreciated.

Happy programming



Tuesday, April 9, 2019

how to setup a schedule task for DotNet Core Console App?

When we publish the dotnet core project either from publish command in visual studio, or use the command line dotnet publish -c Release -r win10-x64 in CMD window.

after we execute the publish command. we can have the following message from the Visual Studio Output Windows

1>------ Publish started: Project: ConsoleAppEncryptDecrypt, Configuration: Release Any CPU ------
1>ConsoleAppEncryptDecrypt -> C:\Users\ddeng\Source\Repos\ConsoleAppEncryptDecrypt\ConsoleAppEncryptDecrypt\bin\Release\netcoreapp2.1\ConsoleAppEncryptDecrypt.dll
1>ConsoleAppEncryptDecrypt -> C:\Users\ddeng\Source\Repos\ConsoleAppEncryptDecrypt\ConsoleAppEncryptDecrypt\bin\Release\netcoreapp2.1\publish\
1>ConsoleAppEncryptDecrypt was published successfully to bin\Release\netcoreapp2.1\publish\
========== Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========
========== Publish: 1 succeeded, 0 failed, 0 skipped ==========

and we can see the compile output in this folder




when we schedule a task with action from this folder. we can use both paths

ConsoleAppEncryptDecrypt\bin\Release\netcoreapp2.1

ConsoleAppEncryptDecrypt\bin\Release\netcoreapp2.1\publish

the schedule task can run succesfully without an error.

However when we move the production server,

if we use this path  ConsoleAppEncryptDecrypt\bin\Release\netcoreapp2.1, the schedule task completed with an error code  3762504530.

the root cause of this issue is that the hosting server do not have the same environment as my local desktop. I have to use the publish folder (ConsoleAppEncryptDecrypt\bin\Release\netcoreapp2.1\publish) which will copy all necessary DLL to folder, in order to run the dotnet core Console app.