Category: components

Interpreter–part 4 of n – Deploy

Series:

  1. http://msprogrammer.serviciipeweb.ro/2018/07/16/interpreterpart-1-of-n/ – Idea
  2. http://msprogrammer.serviciipeweb.ro/2018/07/23/interpreterpart-2-of-n/ – Coding
  3. http://msprogrammer.serviciipeweb.ro/2018/07/30/interpreterpart-3-of-n/ – Testing
  4. http://msprogrammer.serviciipeweb.ro/2018/08/06/interpreterpart-4-of-n/  – Deploy
  5. http://msprogrammer.serviciipeweb.ro/2018/08/13/interpreterpart-5-of-n/ – Documentation
  6. http://msprogrammer.serviciipeweb.ro/2018/08/20/interpreterpart-6-of-n/ – Ecosystem / usage

 

 

After done the testing part, we can deploy the Interpreter . That means uploading to some package sources, as Nuget.org or myget.org. I choose Nuget.org .

For this, first we should package the applicatiuon. We right click the project, select properties, and then package tab.

Enter the details ,. save , then right click the project again and click “Publish” and fisnish.

In the folder “bin\Debug\netcoreapp2.1\publish” you will find the InterpreterDll.1.0.0.nupkg file. This file you will upload to nuget.org. For this, you have to login to nuget.rog and go to https://www.nuget.org/account/Packages

After submitting , you will find the package at https://www.nuget.org/packages/InterpreterDll/ .

From this, you can testit by downloading directly  from nuget feed .

First deploy was simple  – but we want to do this with a button click.

 

But we want more – every time a new code is pushed to github  -the tests should run automatically and a new interpreter package will be created. For this we can choose VisualStudio.com site , integrate with our github repository and create a build release.

I am going to https://ignatandrei.visualstudio.com/ and create a new project.  For this , I will integrate with GitHub and push a new build. Also,  in this definition of build have a publish task that allows to publish as an artifacty the .nupkg that next we will put on github / nuget

Interpreter–part 3 of n -Testing

Series:

  1. http://msprogrammer.serviciipeweb.ro/2018/07/16/interpreterpart-1-of-n/ – Idea
  2. http://msprogrammer.serviciipeweb.ro/2018/07/23/interpreterpart-2-of-n/ – Coding
  3. http://msprogrammer.serviciipeweb.ro/2018/07/30/interpreterpart-3-of-n/ – Testing
  4. http://msprogrammer.serviciipeweb.ro/2018/08/06/interpreterpart-4-of-n/  – Deploy
  5. http://msprogrammer.serviciipeweb.ro/2018/08/13/interpreterpart-5-of-n/ – Documentation
  6. http://msprogrammer.serviciipeweb.ro/2018/08/20/interpreterpart-6-of-n/ – Ecosystem / usage

 

 

Now that we do not have just the interpreter part 1 idea, but also interpreter part 2 coding , we can test the application.

For this we should write test for everything that we wrote in the interpreter part 1  idea  .

That gives us a bunch of tests functions:

void InterpretDateTime();
void InterpretDateTimeUtcNow();
void InterpretEnv();
void InterpretGuid();
void InterpretSettingsFile();
void InterpretStaticOneParameter();
void InterpretStaticParameterString();
void InterpretStaticTwoParameterString();

 

We run those test with VS or

dotnet test

and we think that is ok.

Nope. We should , to be sure,to have the code coverage – means that we verify what we have tested . You can start from here : https://dotnetthoughts.net/code-coverage-in-netcore-with-coverlet/

The first iteration for my project gives to me

Assemblies: 1
Classes: 2
Files: 2
Covered lines: 196
Uncovered lines: 17
Coverable lines: 213
Total lines: 313
Line coverage: 92%
Branch coverage: 84.60%

That it is pretty solid.

Interpreter–part 2 of n – Coding

Series:

  1. http://msprogrammer.serviciipeweb.ro/2018/07/16/interpreterpart-1-of-n/ – Idea
  2. http://msprogrammer.serviciipeweb.ro/2018/07/23/interpreterpart-2-of-n/ – Coding
  3. http://msprogrammer.serviciipeweb.ro/2018/07/30/interpreterpart-3-of-n/ – Testing
  4. http://msprogrammer.serviciipeweb.ro/2018/08/06/interpreterpart-4-of-n/  – Deploy
  5. http://msprogrammer.serviciipeweb.ro/2018/08/13/interpreterpart-5-of-n/ – Documentation
  6. http://msprogrammer.serviciipeweb.ro/2018/08/20/interpreterpart-6-of-n/ – Ecosystem / usage

 

 

Now that we have the idea from interpreter part 1 of what we want to do, start coding thinking about what the code will look like.

We want simple use, like

string textToInterpret = "Export#now:yyyyMMddHHmmss#.csv";
var i = new Interpret();
var nameFile = i.InterpretText(textToInterpret);

So we will have just a function, InterpretText , that will have as a parameter a string and returns the interpreted string.

Now we can start the coding part   .This  is somewhat harder – we make separate functions to interpret environment variables, interpret datetime, guid, interpret file json, and interpret with static functions

For this we will create separate functions , that know how to deal with those cases ( The edge case is loading assemblies – you do not want this time consuming to be done every time you interpret – or to load if it is not necessary)

After this  , in order to have a source control, you upload the code on GitHub : https://github.com/ignatandrei/Interpreter

 

Interpreter–part 1 of n – Idea

Series:

  1. http://msprogrammer.serviciipeweb.ro/2018/07/16/interpreterpart-1-of-n/ – Idea
  2. http://msprogrammer.serviciipeweb.ro/2018/07/23/interpreterpart-2-of-n/ – Coding
  3. http://msprogrammer.serviciipeweb.ro/2018/07/30/interpreterpart-3-of-n/ – Testing
  4. http://msprogrammer.serviciipeweb.ro/2018/08/06/interpreterpart-4-of-n/  – Deploy
  5. http://msprogrammer.serviciipeweb.ro/2018/08/13/interpreterpart-5-of-n/ – Documentation
  6. http://msprogrammer.serviciipeweb.ro/2018/08/20/interpreterpart-6-of-n/ – Ecosystem / usage

 

 

For Stankins I need a custom interpreter of serialized data. What this means, exactly ?

Let’ suppose I have an appsetting file with a connection string

{
“SqlServerConnectionString”: “Server=(local)\\SQL2016;Database=tempdb;Trusted_Connection=True;”
}

If I use directly this connection from code, fine( Please be sure that you read carefully https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1&tabs=basicconfiguration ).

The idea is to have some settings that is generating all time from data. Let’s suppose you have to write a .csv file with some data.You want to be unique every time . The common idea is to hardcode the file with the date time :

string file = “SendTo”+ DateTime.Now.ToString(“yyyyMMdd”) + “.csv”

What if the the name of the file should be serialized  ?  You retrieve from config the first part ( “SendTo”) , append the datetime format and the .csv. Later, you figure a better idea – to have a GUID. You will modify the code again and wrote

string file = “SendTo”+ Guid.NewGuid().ToString(“N”) + “.csv”

What if you will have something like storing the fle name in a appSettings.json like

{

“fileName”:”file:SendTo#now:yyyyMMdd#.csv”

}

retrieve with configuration

var builder = new ConfigurationBuilder()
.AddJsonFile(filePath);
var config = builder.Build();

var fileName = config[“fileName”]

and then interpret:

var i = new Interpret();
var str = i.InterpretText(fileName );

 

This will give you in the str the string SendTo20180710.csv.

Next time, when you want Guid, you just modify the appSettings.json

{

“fileName”:”SendTo#guid:N#”.csv”

}

The code remains the same for interpret:

var i = new Interpret();
var str = i.InterpretText(fileName );

 

but the result will be different ,with the guid into the filename

What I intend to support:

-file: appSettings.json

-env: environment

-static: static functions with one variable

-guid: Guid.NewGuid

-now : datetime

But the idea is that I have a class that serializes itself as follow:

{

“ConnectionString”:”#file:SqlServerConnectionString#”,

“FileName”: “SendTo#now:yyyyMMdd#.csv”,

“DriveRoot”:”@static:Path.GetPathRoot(#static:Directory.GetCurrentDirectory()#)@”

“NameSln”:”@static:System.IO.Path.GetFileNameWithoutExtension(#env:solutionPath#)@”,

“newFileName”:”#guid:N#.csv”

}

The first item will be interpreted as ConnectionString : “Server=(local)\\SQL2016;Database=tempdb;Trusted_Connection=True;”

The second item will be interpreted as FileName: “SendTo20180710.csv”

The third item will call the static functions( Directory.GetCurrentDirectory() , Path.GetPathRoot)   from C# and return the result

The fourth item will call Environment variable solutionPath  and give back as an argument to the static function System.IO.Path.GetFileNameWithoutExtension

The fifth will call Guid.NewGuid().ToString(“N”)

All in all, it is another redirection and interpreting of data.

 

MVC 5 encrypt parameters

 

This is an old idea that I was having. The problem was that , for many people, showing the parameters in MVC is not something that they want . For example. suppose that we have this action

 

public ActionResult TestEncrypt(int id, int a, string b)

 

The this action can be activated by putting in the Razor cshtml file this

 

<a href=’@Url.Action("TestEncrypt", new { id=7, a = 1, b = "asd" })’>Test</a>

 

that will generate this URL :

http://mvc5encrypt.apphb.com/Home/TestEncrypt/7?a=1&b=asd .

The parameters are passed in clear text ( a is 1 and b is asd). What if I want to encrypt those into the URL ,

http://mvc5encrypt.apphb.com/Home/TestEncrypt/7?a=EAAAAHT3XGpsOow%2f2Wto%2fho1C3Bmy1kTFnBosorsrt9X3Eqj&b=EAAAADbjm%2bS8NDAKqznGI%2bzF02oOAY9wf24SFyFxPxbCu0ea

 

but receive in the Action the default values ( 1 and asd)?

Enter MVC5Encrypt

What you have to do is modify slightly the code in the .cshtml and add an attribute to the Action

 

<a href=’@Url.ActionEnc("mySecret", "TestEncrypt", new { id=7, a = 1, b = "asd" })’>Test</a>

 

and the action will be

[MVCDecryptFilter(secret = &quot;mySecret&quot;)]   
public ActionResult TestEncrypt(int id, int a, string b)

 

You can see into action at

http://mvc5encrypt.apphb.com/Home/TestEncrypt/7?a=EAAAAHT3XGpsOow%2f2Wto%2fho1C3Bmy1kTFnBosorsrt9X3Eqj&b=EAAAADbjm%2bS8NDAKqznGI%2bzF02oOAY9wf24SFyFxPxbCu0ea

 

FAQ:

1.  What is “mysecret”?

See code on http://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string that I shameless copied.

 

2. What about backward compatibility ( i.e., old links will function ) ?

Yes if you do not already encode in base64 ( default class encrypter knows if the parameter value is in base64 ) . See

http://mvc5encrypt.apphb.com/Home/TestEncrypt/7?a=1&b=asd 

 

3. What about extending this with a custom encrypt class ?

You can – see this function

 

public static string ActionEnc(this UrlHelper helper, IEncryptDecrypt encDec, string actionName, object routeValues)

 

4. What about extending this to route parameters ( e.g. http://localhost/Person/Edit/5  – the 5 parameter is in the route and not encrypted ) ?

Glad you ask. Please fill an feature request on github

5. More details ? 

Sources on GitHub : https://github.com/ignatandrei/MVC5Encrypt

Demo at http://mvc5encrypt.apphb.com/ 

NuGet at https://www.nuget.org/packages/MVC5Encrypt/

( Other solution is to use http://madskristensen.net/post/httpmodule-for-query-string-encryption)

.tt files to maintain assembly version in sync

Let’s suppose you have a medium-big application and you have several dll-assemblies-component that the main application references( DAL, BLL). You have several deployments of the application at clients and , when a client , you must find each version of each assembly deployed.

I have developed a simple .tt file to  ensure that every component that you compile have the same version – you can run on the server on the automatic build(http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration/) or by hand.

More, with this .tt file you can

    1. Have the date /time ( with minute) of the compile of the dll embedded into version information
    2. Read a text file and add same copyright to all projects( left as an exercise to the user) .

 

You can see the demo at http://youtu.be/PudBWl16308 .

You can download the project at https://github.com/ignatandrei/AssemblyInfoTT

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.