[{"content":"One of the most complex things to manage in the development of any application, from simple client applications to the most complex enterprise solutions, concerns the management of persistence.\nIn the .NET environment some of this complexity can be managed through the use of migrations implemented internally in Entity Framework.\nOften this feature is seen as a utility purely for the use of developers to update the database schema.\nWhen we think we have arrived at a stable situation we drop all migration and start from a clean situation.\nThis is a phrase that I have heard really too often from many colleagues, used more or less consciously, often the reasons that lead to outsourcing in this sense is an insufficient analysis of the problem that generates many changes, even destructive changes, of the databases.\nOther times more conscious and driven by a desire not to keep versions earlier than the one we assume will hold &ldquo;real&rdquo; data, often this coincides with the first production release.\nActually, what the tool offers us is an incremental versioning system something that goes far beyond the scope of the developer by also involving DBA or more properly DBRE.\nHow can I perform operations on the data? This thing is one of those operations that is not possible to instruct in a migration through the APIs that Entity Framework makes available to us as it is very domain dependent and trying to formalize this through APIs would have been very complex if not impossible and it is for these cases that the loophole for running raw SQL scripts was provided.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public partial class InitialWithSeed : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.Sql(@&#34;CREATE TABLE Persons ( Id int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) ); INSERT INTO Persons (Id, LastName, FirstName, Address, City) VALUES (1, &#39;Nesfield&#39;, &#39;Carmelia&#39;, &#39;802 Knutson Drive&#39;, &#39;Krajan Dua Putukrejo&#39;), (2, &#39;Valentino&#39;, &#39;Daune&#39;, &#39;1464 Forest Dale Road&#39;, &#39;Prozor&#39;), (3, &#39;Chrstine&#39;, &#39;Gus&#39;, &#39;817 Bonner Park&#39;, &#39;Lukunor&#39;), (4, &#39;Tebb&#39;, &#39;Stearne&#39;, &#39;63138 Colorado Plaza&#39;, &#39;Sanjiang&#39;), (5, &#39;Dyne&#39;, &#39;Gibby&#39;, &#39;39613 Pond Road&#39;, &#39;Th\u00e0nh Ph\u1ed1 H\u1ea1 Long&#39;), (6, &#39;MacShane&#39;, &#39;Sandra&#39;, &#39;02617 Continental Parkway&#39;, &#39;Cihambali&#39;), (7, &#39;Lissandri&#39;, &#39;Sidney&#39;, &#39;61 Talmadge Circle&#39;, &#39;Langar\u016bd&#39;), (8, &#39;O&#39;&#39; Quirk&#39;, &#39;Marc&#39;, &#39;828 Ohio Avenue&#39;, &#39;Farafangana&#39;), (9, &#39;Mabee&#39;, &#39;Man&#39;, &#39;79 Crownhardt Street&#39;, &#39;Kembang&#39;), (10, &#39;Izak&#39;, &#39;Bertie&#39;, &#39;7 High Crossing Junction&#39;, &#39;Taodian&#39;);&#34;); } } The example just given might turn the nose up at both categories.\nTo the developers because there are strings within the source and to the DBRE because they would find themselves working &ldquo;inconveniently&rdquo; without auto-completion.\nHow to make both worlds happy? One feature of the tool is to generate partial classes that are matched with content classes in files named {MigrationId}.Design.cs\n1 2 3 4 5 6 [DbContext(typeof(DesignContext))] [Migration(&#34;20220624071324_InitialWithSeed&#34;)] partial class InitialWithSeed { ... } which hold the other part of the partial class decorated with an attribute identifying the context to which it is bound and one representing its identifier.\nWe can then think of extracting the SQL script within a file with the .sql extension and exploit the runtime migration identifier to read it and integrate it within the migration.\nOur migration will then have this content\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public partial class InitialWithSeed : Migration { protected override void Up(MigrationBuilder migrationBuilder) { var migrationAttribute = (MigrationAttribute)this.GetType() .GetCustomAttributes(typeof(MigrationAttribute), false) .Single(); migrationBuilder.Sql(File.ReadAllText(string.Format( CultureInfo.InvariantCulture, &#34;{1}{0}RawMigrations{0}{2}&#34;, Path.DirectorySeparatorChar, AppContext.BaseDirectory, $&#34;{migrationAttribute.Id}.sql&#34;))); } } and the SQL script can then be read from the path relative to the execution directory \/RawMigrations\/20220624071324_InitialWithSeed.sql\nLet us also remember to add the instruction\n1 2 3 &lt;ItemGroup&gt; &lt;None Include=&#34;RawMigrations\\*.sql&#34; CopyToOutputDirectory=&#34;PreserveNewest&#34; \/&gt; &lt;\/ItemGroup&gt; within the .csproj to instruct MSBuild to publish the files to the target folder.\nAs always you can view the full sample design at\nbinick \/ samples ","permalink":"https:\/\/binick.blog\/2022\/07\/02\/how-to-use-a-raw-sql-script-with-entity-framework-migrations\/","summary":"<p>One of the most complex things to manage in the development of any application, from simple client applications to the most complex enterprise solutions, concerns the management of persistence.<\/p>\n<p>In the .NET environment some of this complexity can be managed through the use of <a href=\"https:\/\/docs.microsoft.com\/ef\/core\/managing-schemas\/\">migrations<\/a> implemented internally in Entity Framework.<\/p>\n<p>Often this feature is seen as a utility purely for the use of developers to update the database schema.<\/p>\n<blockquote>\n<p>When we think we have arrived at a stable situation we drop all migration and start from a clean situation.<\/p>","title":"How to use a raw SQL script with Entity Framework migrations?"},{"content":"Many of you may know that for some time, now 13 years1, GitHub has offered a service called Pages that allows you to host static sites, which is very convenient for hosting blogs and documentation.\nThat&rsquo;s why it&rsquo;s not news that this blog, like many others, is hosted right there. And the reason is not because it&rsquo;s &ldquo;cool&rdquo; but much more concrete and venal.\nOne of the goals I set for myself was to not make it a living expense, so I chose the HUGO + GitHub Pages combo, a choice I would make again today! For once I can pat myself on the shoulder \ud83d\ude42.\nI later thought that in order to have a better SEO and more association between this blog and me, it would be good to have some custom domains.\nEnforcing HTTPS. I got the domains from ()register.it and I chose to use the DNS service from Cloudflare so after I configured the DNS records to support custom domains by having the apex and www point to the github.io subdomain.\nAt this point although the Pages section of the repo settings reset the flag on the correctness of the DNS records set the message immediately below informed me that the domain was not properly configured\nAlso the section Custom domain names that are unsupported confirmed the validity of the configuration and this caused me a big headache until I found this post from which I quote verbatim.\nIf you\u2019re configuring an apex domain make sure there are no other A, AAAA, or ALIAS records listed on the apex.\nIf you\u2019re configuring a subdomain, www or otherwise, make sure there are no other A, AAAA, or CNAME records on that same subdomain.\nSomewhat discouraged, I removed the www record and despite the documentation and the appearance of this warning\n(sorry but I forgot to capture the screen \ud83d\ude4f so I retrieved it from an issue where I found out that other people had the same headache as me)\nI don&rsquo;t have that much memory but Wikipedia attributes the first release of the service to 2008.&#160;&#x21a9;&#xfe0e;\n","permalink":"https:\/\/binick.blog\/2022\/06\/01\/github-pages-and-the-confusing-process-for-enforcing-https\/","summary":"<p>Many of you may know that for some time, now 13 years<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\">1<\/a><\/sup>, GitHub has offered a service called <a href=\"https:\/\/pages.github.com\/\">Pages<\/a> that allows you to host static sites, which is very convenient for hosting blogs and documentation.<\/p>\n<p>That&rsquo;s why it&rsquo;s not news that this blog, like many others, is hosted right there. And the reason is not because it&rsquo;s &ldquo;cool&rdquo; but much more concrete and venal.<br>\nOne of the goals I set for myself was to not make it a living expense, so I chose the <a href=\"https:\/\/gohugo.io\/\">HUGO<\/a> + GitHub Pages combo, a choice I would make again today! For once I can pat myself on the shoulder \ud83d\ude42.<\/p>","title":"Github pages and the confusing process for enforcing HTTPS"},{"content":" I was recently asked to make a spike1 to evaluate the feasibility of implementing a micro frontends architecture with Blazor Server.\nI&rsquo;ll tell you right now that it was a failure; but let&rsquo;s go in order, first analyzing the declension of the term failure and the reasons that led me to use it and then try to recapitulate what emerged from this exploration that led me to this conclusion.\nI really like the definition he gives Treccani.\nRiconoscere l&rsquo;inutilit\u00e0 dei propri sforzi, l&rsquo;impossibilit\u00e0 e incapacit\u00e0 di raggiungere gli scopi fissati, rinunciando definitivamente alla lotta, all&rsquo;azione.\n&ndash; Treccani\nWhich translated, hoping to do it correctly, would be &ldquo;Recognizing the futility of one&rsquo;s efforts, the impossibility and inability to achieve the set goals, definitely giving up the struggle, action.&rdquo;\nI find it particularly proper because it uses the term fixed scopes, and so what are those purposes?\nContext matters. Nothing is done by accident, and this is certainly no exception. The work done is part of a larger context involving the need to migrate a number of ASP.NET MVC 5 applications to ASP.NET Core combined with a desire to make the current architecture more flexible by introducing the concept of modular-programming2.\nWithout getting around too much, the ultimate goal was to measure the feasibility of &ldquo;realizing&rdquo; a micro frontends architecture rendered server-side thanks to Blazor Server.\nIn this regard on Martin Fowler&rsquo;s blog there is a nice article by Cam Jackson in which an overview of this architecture is given and from which I have translated their definition of micro frontends\nAn architectural style where independently deliverable frontend applications are composed into a greater whole.\n&ndash; Thoughtworks su martinfowler.com\nI put realize in quotes since the deployment of the various sites would only ever be done in a unified manner.\nPerhaps we would address this issue in a future post.\nNot all donuts come out with a hole. Don&rsquo;t you know what it means? A clear explanation of what this Italian saying means I found in Clozemaster at point 4. Anyway, in two words it means that despite failure there is still something left to eat! Getting straight to the point, the main reason for the failure is related to the inability to give complete autonomy to the teams, for two main distinct reasons.\nHomonymy in support for pages and views Razor. To compose the site each frontends is contained within a Razor class library which also holds the view that is responsible for doing hosting of the Blazor application.\nThis is made possible by the functionality exposed by the SDK that allows a web app to use Razor views, pages, or layouts from class libraries and, as defined in the official documentation, in case of homonymy, precedence is given to the view, page, layout present in the web app.\nIn my case I am in a situation like this\nFigure 1: an ASP.NET Core application referencing two Razor Class Library representing two modules.\nwhere both modules internally make use of layouts contained at the \/Pages\/Shared\/_Layout.cshtml path.\nHere, what would happen in this case is that one of the two teams would be displeased since, if it went well it would see its application rendered inside another layout, in the worst case one part or all of the views would go wrong (e.g., a view tries to enhance a section not declared in the layout). And we note well that both modules executed independently would behave as expected.\nRoutes, the basic route that does not want to work. I have that at least I could not get it to work.\nAgain, following the principle of autonomy, the desired was to separate the module routes from the container routes, for example within Module A we would find \/ or \/index while from the container perspective the routes would be \/module-a\/ or \/module-a\/index.\nWhat I found was a &ldquo;short blanket,&rdquo; when internal navigation within the module worked, route generation using Anchor Tag Helper did not work (remember that this spike is the result of a migration process), as I used the middleware UsePathBaseMiddleware for the implementation of the requirement.\nThis resulted in the generation of links within the module to the outside always adding the \/module-a at the top of the address even as the link should have simply pointed to the container.\nOtherwise using middleware I would have been forced to use the module name at the top of all @page directives.\nConclusions. Summing up what has been done and reasoning with a cool mind I could say that something good we can still take home, in fact, by not enabling support for Razor pages and views in a RCL3 and avoiding the use of Anchor Tag Helper in the HTML markup that contributes to view rendering we would not run into these problems.\nA spike is a product development method originating from extreme programming that uses the simplest possible program to explore potential solutions. Source Wikipedia.&#160;&#x21a9;&#xfe0e;\nModular programming is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each holds everything necessary to execute only one aspect of the desired functionality. Source Wikipedia.&#160;&#x21a9;&#xfe0e;\nRazor Class libraries (RCLs) were introduced in ASP.NET Core 2.1 as a way to package and distribute UI components to be referenced and consumed within a host application.&#160;&#x21a9;&#xfe0e;\n","permalink":"https:\/\/binick.blog\/2022\/05\/22\/micro-frontends-and-blazor-server-the-beginning-of-the-journey\/","summary":"Not all donuts come out with a hole, but that doesn&rsquo;t mean there isn&rsquo;t good in them. I stumbled upon one of these in an attempt to implement a micro frontends architecture with Blazor Server.","title":"Micro frontends and Blazor Server, the beginning of the journey"},{"content":"I&rsquo;m not a writer, I&rsquo;ve never been one, and I&rsquo;ve known this since my school essays. Every time I passed the column and a half it was a challenge.\nPublishing articles on a regular basis takes up a lot of my time, and not just strictly for writing. So I took inspiration from Troy Hunt and thought that creating a monthly summary to update you on my current status and possible future directions might be a good investment of time.\nThis thing, if I can pursue it over time, will also be useful to me tomorrow.\nRecap 0. Exactly one month ago today I announced a new side project. Well, I managed to create the first strategy regarding resource naming in Azure.\nThe next step is to define the other two strategies, concerning localisation and tagging.\nI also plan to create a library in Python so that I can integrate it into the Azure CLI.\nReferences. Build your own Azure CLI Extensions: great article on how to create an extension to the Azure CLI. ","permalink":"https:\/\/binick.blog\/2022\/04\/29\/monthly-recap-0\/","summary":"<p>I&rsquo;m not a writer, I&rsquo;ve never been one, and I&rsquo;ve known this since my school essays. Every time I passed the column and a half it was a challenge.<\/p>\n<p>Publishing articles on a regular basis takes up a lot of my time, and not just strictly for writing. So I took inspiration from <a href=\"https:\/\/www.troyhunt.com\/tag\/weekly-update\/\">Troy Hunt<\/a> and thought that creating a monthly summary to update you on my current status and possible future directions might be a good investment of time.<\/p>","title":"Monthly recap 0"},{"content":"A few years ago, when I was commuting to work by car, there was a tree-lined stretch of country road along a stream. Within this area there was a very narrow chicane at the exit immediately following a slight descent that followed a long straight. Given the presence of the stream and the permanent shade caused by the trees, it was not uncommon that on some winter mornings there was the presence of ice.\nI never had any accidents there as I was aware of the potential danger and even though the straightaway led to pushing on the accelerator I held back.\nWhat do I want to tell you with this anecdote?\nThat prevention is better than cure?\nNot really, the message is more subtle and is about instinct and consciousness.\nWhat if someone just happened to walk by on one of those mornings?\nAnd maybe even late for his appointment?\nIn all likelihood they would be forced to call the tow truck as they would be unaware of the presence of ice and would step on the brake pedal to reduce their speed on the curve. With consequent loss of grip and a car in the ditch.\nWhat would be the potential consequences?\nLet&rsquo;s assume that after this unfortunate &ldquo;adventure&rdquo; the driver gets out of the car unharmed, what would be the other consequences?\nI would say two, a lightened wallet and a missed appointment.\nA typical approach to OpEx. I guess you are wondering what is the purpose and the reason of this parable.\nYou must know that some time ago I attended some meetings about the migration of a business application for internal use in Azure in which many issues arose due to the permissions assigned to users.\nProblems that have caused the postponement of the production release of a business application for internal use by more than two weeks.\nLet&rsquo;s try, with not exactly little effort, to transpose the parable of the unfortunate driver within this context; we can identify the road as the cloud, the person driving the car as the company. And I&rsquo;d say let&rsquo;s stop there for now.\nTypically when a company approaches the cloud one of the main concerns is cost management1.\nImagine being a member of the security operations team, used to operating on a predetermined set of machines, who now finds himself with a potentially infinite fleet of machines and a warning from his area manager telling him he must contain his expenses.\nThe only thing it knows of that is more like what it has used so far is the role-based access control of Active Directory which finds its counterpart Azure RBAC also configurable from Azure Active Directory.\nWhat would you do? I think I would limit access to all users by giving only the minimum permissions necessary to members of the development team, but I think you would do the same.\nAnd that&rsquo;s what the team did, so they set up two resource groups, one to house all the resources related to networking issues and one for the development team giving them the role of Contributor for the latter.\nSlipping into misuse of resource groups improperly in that some resources such as for example the Azure Kubernetes service relies on a third resource group to host agent pool nodes shared between us and the service itself.\nEducate rather than impose. The SecOps team failed because they were unaware of the meaning of the term Cloud Governance and the tools that Azure offers to support it.\nObviously, the team acted in good faith by trying to limit each team&rsquo;s scope2 of action.\nThinking to achieve two goals: cost control3 and security4.\nHere we now have the necessary elements to resume the transposition begun earlier and identify the ambit2 in the jacke, the release date in the date, and the five disciplines of Cloud Governance in the awareness.\nHere that to try to increase this awareness I created this repository\nbinick \/ oh-my-azure-playground whose intent is to define standards based on best practices that have emerged in areas such as resource naming, tag management and localization.\nOn which it will then be possible to define patterns for the definition of budget3.\nOver the years I&rsquo;ve started several side projects but never had a post like this one.\nI see this as a first step towards a real commitment, if you would like to elaborate or feel the need to contribute please feel free to contact me \ud83d\ude42 .\nCapEx vs OpEx in Cloud Computing&#160;&#x21a9;&#xfe0e;\nUnderstand scope for Azure RBAC&#160;&#x21a9;&#xfe0e;&#160;&#x21a9;&#xfe0e;\nWhat is Cost Management + Billing?&#160;&#x21a9;&#xfe0e;&#160;&#x21a9;&#xfe0e;\nIntroduction to Azure security&#160;&#x21a9;&#xfe0e;\n","permalink":"https:\/\/binick.blog\/2022\/03\/29\/a-new-side-project\/","summary":"<p>A few years ago, when I was commuting to work by car, there was a tree-lined stretch of country road along a stream. Within this area there was a very narrow chicane at the exit immediately following a slight descent that followed a long straight.\nGiven the presence of the stream and the permanent shade caused by the trees, it was not uncommon that on some winter mornings there was the presence of ice.<\/p>","title":"A new side project"},{"content":"I started working in remote mode in March 2020, the reason I guess we all know.\nHowever, if an extra-terrestrial were to read this post, he can find more information here https:\/\/wikipedia.org\/wiki\/COVID-19.\nMy experience has been the same as that of so many others, a maximum and indiscriminate use of communication platforms and smoking ears at the end of the day.\nThis working mode went on for about a year and a half, 16 months to be precise, until July 2021 when I joined managed\/designs.\nHere I found a different environment, which some would call smart. Devoted to personal growth and continuous improvement where autonomy and trust are two pillars on which the daily collaboration is based.\nPrologue. I&rsquo;ve never been a user of to-do lists, perhaps due to inexperience or perhaps due to some belief unknown to me. The fact is that the systematic failure to follow the shopping list is proof of it &ldquo;Nicola is not able to manage the lists&rdquo;.\nOnce I became aware of this, I started looking for possible patterns and\/or methodologies by identifying some that have accompanied me for a couple of months.\nMy inbox is not the email. I realized that what I need is not a list of tasks to do but rather a list of things that I would like to do or that somehow pique my interest. I suspect that on a subconscious level, my brain takes optimistically to the presence of that &ldquo;would like&rdquo; that removes the pressure for things that shouldn&rsquo;t be there.\nI have three emails, the corporate one and two other historical ones that I&rsquo;ve been carrying around for at least a decade, all three of which follow the philosophy of Inbox Zero by Merlin Mann. I currently flip through them twice a day, roughly before lunch and before the end of the day, these slots are recurring appointments on the calendar until next June 29, so we&rsquo;ll see if they will be extended, but I think so.\nThe rule is very easy:\nit is important and must be executed at a specific time: an appointment is created on the calendar and archived in the corresponding inbox it is important: it ends up in the inbox and archived it interests me: it ends up in the inbox and deleted it doesn&rsquo;t interest me: it ends up in the trash In this way, I always have free inboxes and can keep my attention on those ten or so emails.\nIf an email comes in requesting an active response, I won&rsquo;t run it right away, but like the others, it will follow the rules above.\nOne frog a day is enough. The other enlightening technique for me was the discovery of the 1-3-5 rule1 based on the practice of eating a frog as soon as you wake up2. Obviously not physically, I never want to wake up, and I&rsquo;ve also been getting very little sleep lately!\nSo the day before I make a list of what I&rsquo;d like to do the next day, applying some sort of empirical prioritization of activities of the moment while always making sure there&rsquo;s at least one frog and possibly other filler activities.\nEpilogue. I have to be honest, at first I was skeptical about taking the time to plan my tomorrow. I have to reconsider. The benefits of freeing my brain from the burden of thinking about what to do so that I don&rsquo;t run the risk of losing it forever is something to be reckoned with.\nRight now, the rigidity of the calendar and the flexibility that the 1-3-5 list leaves me with are a good match. Only time will tell if it is a winning choice for me.\nWhy You Never Finish Your To-Do Lists at Work (And How to Change That) by Alex Cavoulacos&#160;&#x21a9;&#xfe0e;\nEat That Frog: Brian Tracy Explains the Truth About Frogs by Brian Tracy&#160;&#x21a9;&#xfe0e;\n","permalink":"https:\/\/binick.blog\/2022\/02\/18\/that-time-i-tasted-a-frog\/","summary":"<p>I started working in remote mode in March 2020, the reason I guess we all know.<\/p>\n<blockquote>\n<p>However, if an extra-terrestrial were to read this post, he can find more information here <a href=\"https:\/\/wikipedia.org\/wiki\/COVID-19\">https:\/\/wikipedia.org\/wiki\/COVID-19<\/a>.<\/p>\n<\/blockquote>\n<p>My experience has been the same as that of so many others, a maximum and indiscriminate use of communication platforms and smoking ears at the end of the day.<br>\nThis working mode went on for about a year and a half, 16 months to be precise, until July 2021 when I joined <a href=\"https:\/\/www.manageddesigns.it\/\"><em>managed\/designs<\/em><\/a>.<\/p>","title":"That time I tasted a frog"},{"content":"We will see how it&rsquo;s possible to create a solution that integrates Azure Active Directory B2C to save on Blob Storage dummy data at user registration.\nSolution overview. The solution is composed as follows:\nSolution composition\nread-customer-details-identity-la: represents the API whose purpose is to retrieve the content of the blob from customersstgacc (the storage account) customer-register-tpc: is the topic in which are collected the events of the creation of a new user customer-identity-details-filler-la: it represents the API that is in charge of generating fictitious data that will be saved inside a blob on the customersstgacc contoso-b2c: is the access and identity management service offered by Azure Introduction to Azure Event Grid. In Azure there is an implementation of the publish\/subscribe pattern designed to facilitate integration and resource management via an event-driven development paradigm.\nThrough the Event Grid will be possible to subscribe to built-in message sources via a set of handlers.\nIf this is not enough, it is possible to create custom _topics to which you can subscribe to receive events.\nCreating a custom topic. You can refer to this guide to create a topic.\nOne choice to make when creating the topic concerns the scheme of the HTTP request content used. Currently, supported schemas are:\nEvent Grid Schema Cloud Event Schema Custom Input Schema this schema will require the creation of an association between the properties of the input object and those required by the Event Grid Schema The message used in this case has the following structure\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ { &#34;data&#34;: { &#34;objectId&#34;: &#34;25100647-****-4571-****-b03e4ce72d02&#34; \/\/ unique user identifier }, &#34;id&#34;: &#34;25100647-****-4571-****-b03e4ce72d02&#34;, \/\/ unique message identifier, the same of `data.objectId` in this case &#34;eventType&#34;: &#34;Microsoft.ActiveDirectory&#34;, &#34;subject&#34;: &#34;*.onmicrosoft.com&#34;, &#34;dataVersion&#34;: &#34;1.0&#34;, &#34;metadataVersion&#34;: &#34;1&#34;, &#34;eventTime&#34;: &#34;2021-12-03T21:04:03.8504745Z&#34;, &#34;topic&#34;: &#34;\/subscriptions\/{your-subscription-id}\/resourceGroups\/{your-resource-group}\/providers\/Microsoft.EventGrid\/topics\/{your-event-grid-topic}&#34; } ] Issuing the registration event. Sending events to the topic is done using a RESTful technical profile.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 &lt;TechnicalProfile Id=&#34;AAD-UserEmitRegistrationEvent&#34;&gt; &lt;DisplayName&gt;Emit user registration event to Event Grid.&lt;\/DisplayName&gt; &lt;Protocol Name=&#34;Proprietary&#34; Handler=&#34;Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&#34; \/&gt; &lt;Metadata&gt; &lt;Item Key=&#34;ServiceUrl&#34;&gt;{Settings:CustomerRegisteredTopicUrl}&lt;\/Item&gt; &lt;Item Key=&#34;AuthenticationType&#34;&gt;ApiKeyHeader&lt;\/Item&gt; &lt;Item Key=&#34;SendClaimsIn&#34;&gt;Body&lt;\/Item&gt; &lt;Item Key=&#34;ClaimUsedForRequestPayload&#34;&gt;userRegisterEvent&lt;\/Item&gt; &lt;Item Key=&#34;DefaultUserMessageIfRequestFailed&#34;&gt;Cannot process your request right now, please try again later.&lt;\/Item&gt; &lt;\/Metadata&gt; &lt;CryptographicKeys&gt; &lt;Key Id=&#34;aeg-sas-key&#34; StorageReferenceId=&#34;B2C_1A_CustomerRegisteredTopicSas&#34; \/&gt; &lt;\/CryptographicKeys&gt; &lt;InputClaimsTransformations&gt; &lt;InputClaimsTransformation ReferenceId=&#34;GetSystemDateTime&#34; \/&gt; &lt;InputClaimsTransformation ReferenceId=&#34;GenerateRegistrationEventRequest&#34; \/&gt; &lt;\/InputClaimsTransformations&gt; &lt;InputClaims&gt; &lt;InputClaim ClaimTypeReferenceId=&#34;userRegisterEvent&#34; \/&gt; &lt;\/InputClaims&gt; &lt;PersistedClaims&gt; &lt;PersistedClaim ClaimTypeReferenceId=&#34;systemDateTime&#34; \/&gt; &lt;\/PersistedClaims&gt; &lt;UseTechnicalProfileForSessionManagement ReferenceId=&#34;SM-AAD&#34; \/&gt; &lt;\/TechnicalProfile&gt; This fragment of markup translated into curl command, for more explicability, would look like this:\n1 curl -X POST -H &#34;aeg-sas-key: $key&#34; -d &#34;$event&#34; $endpoint where the authentication requirements are met by the AuthenticationType metadata to which is associated the cryptographic key aeg-sas-key whose value is retrieved from the key B2C_1A_CustomerRegisteredTopicSas present in the collection of policy keys.\nTL;DR The choice of the topic template in this example was guided by the limitations currently imposed by the RESTful technical profile regarding the possibilities of building the HTTP request, in fact for a combination of criteria it is not possible to pass information in the headers and the body of the request at the same time.\nThis makes it impossible to send towards a topic schemes of type Cloud Event since the protocol, in version 1.0 requires the presence of a mandatory header.\nMuch more complex is the creation of the body of the request for which it is necessary:\nuse the InputClaimsTransformation add two statements inside the baggage userRegisterEvent and systemDateTime both of type string. Finally, the technical profile has been added among the technical validation profiles of LocalAccountSignUpWithLogonEmail so that the event is issued only when a user is registered.\nUsing claim transformations. During the creation of custom criteria we could have the necessity to execute calculations, as the number of attempts of authentication, that even if very simple would result impossible without the execution of functions.\nThis requirement finds expressivity through the ClaimsTransformation whose reference of the transformations of the claims contains the complete list of the transformations usable.\nIn the example the methods GetCurrentDateTime and GenerateJson were used\n1 2 3 4 5 &lt;ClaimsTransformation Id=&#34;GetSystemDateTime&#34; TransformationMethod=&#34;GetCurrentDateTime&#34;&gt; &lt;OutputClaims&gt; &lt;OutputClaim ClaimTypeReferenceId=&#34;systemDateTime&#34; TransformationClaimType=&#34;currentDateTime&#34; \/&gt; &lt;\/OutputClaims&gt; &lt;\/ClaimsTransformation&gt; The purpose of GetSystemDateTime is to enhance the systemDateTime claim.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 &lt;ClaimsTransformation Id=&#34;GenerateRegistrationEventRequest&#34; TransformationMethod=&#34;GenerateJson&#34;&gt; &lt;InputClaims&gt; &lt;InputClaim ClaimTypeReferenceId=&#34;objectId&#34; TransformationClaimType=&#34;0.data.objectId&#34; \/&gt; &lt;InputClaim ClaimTypeReferenceId=&#34;objectId&#34; TransformationClaimType=&#34;0.id&#34; \/&gt; &lt;InputClaim ClaimTypeReferenceId=&#34;systemDateTime&#34; TransformationClaimType=&#34;0.eventTime&#34; \/&gt; &lt;\/InputClaims&gt; &lt;InputParameters&gt; &lt;InputParameter Id=&#34;0.dataVersion&#34; DataType=&#34;string&#34; Value=&#34;1.0&#34; \/&gt; &lt;InputParameter Id=&#34;0.eventType&#34; DataType=&#34;string&#34; Value=&#34;Microsoft.ActiveDirectory&#34; \/&gt; &lt;InputParameter Id=&#34;0.subject&#34; DataType=&#34;string&#34; Value=&#34;{Settings:Tenant}&#34; \/&gt; &lt;\/InputParameters&gt; &lt;OutputClaims&gt; &lt;OutputClaim ClaimTypeReferenceId=&#34;userRegisterEvent&#34; TransformationClaimType=&#34;outputClaim&#34; \/&gt; &lt;\/OutputClaims&gt; &lt;\/ClaimsTransformation&gt; GenerateRegistrationEventRequest has instead the burden of constructing the JSON and enhancing the userRegisterEvent claim.\nConclusions. In this article, we have seen how through Identity Experience Framework it is possible to integrate a B2C tenant with our infrastructure and open possible interesting development scenarios.\nTo do this we touched on Azure Event Grid and how to create an Event Grid Topic.\nFinally how you can manipulate attestations and use them within technical profiles.\nIf you are interested in the complete example you can find it at https:\/\/github.com\/binick\/samples\/tree\/master\/src\/enrich-a-jwt-token-with-ief.\n","permalink":"https:\/\/binick.blog\/2022\/01\/08\/develop-integrated-solutions-with-active-directory-b2c-and-azure-event-grid.\/","summary":"<p>We will see how it&rsquo;s possible to create a solution that integrates Azure Active Directory B2C to save on Blob Storage dummy data at user registration.<\/p>\n<h2 id=\"solution-overview\">Solution overview.<\/h2>\n<p>The solution is composed as follows:<\/p>\n<figure class=\"align-center background-light\">\n    <img loading=\"lazy\" src=\"component-map.svg#center\"\n         alt=\"Solution composition\"\/> <figcaption>\n            <p>Solution composition<\/p>\n        <\/figcaption>\n<\/figure>\n\n<ul>\n<li><code>read-customer-details-identity-la<\/code>: represents the API whose purpose is to retrieve the content of the <em>blob<\/em> from <code>customersstgacc<\/code> (the <em>storage account<\/em>)<\/li>\n<li><code>customer-register-tpc<\/code>: is the <em>topic<\/em> in which are collected the events of the creation of a new user<\/li>\n<li><code>customer-identity-details-filler-la<\/code>: it represents the API that is in charge of generating fictitious data that will be saved inside a <em>blob<\/em> on the <code>customersstgacc<\/code>\n<figure class=\"align-center \">\n    <img loading=\"lazy\" src=\"logic-app-steps.png#center\"\n         alt=\"Logic app definition\"\/> \n<\/figure>\n<\/li>\n<li><code>contoso-b2c<\/code>: is the access and identity management service offered by <em>Azure<\/em><\/li>\n<\/ul>\n<h2 id=\"introduction-to-azure-event-grid\">Introduction to <em>Azure Event Grid<\/em>.<\/h2>\n<p>In <em>Azure<\/em> there is an implementation of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Publish%E2%80%93subscribe_pattern\">publish\/subscribe<\/a> pattern designed to facilitate integration and resource management via an event-driven development paradigm.<\/p>","title":"Develop integrated solutions with Active Directory B2C and Azure Event Grid."},{"content":"By code coverage, we mean the action of trying to measure how much of our code has been executed by our tests. This sound like\nTL;DR Untested code is a broken code. Definitely a strong statement but true in a way, we don&rsquo;t always manage to get enough coverage. Often this happens because we don&rsquo;t have time, other times because despite having written tests we are not able to read the metrics.\nSo, how we can &ldquo;humanize&rdquo; code coverage metrics? And how we can generate its?\nTo answer at these questions I usually use two libraries.\ncoverlet-coverage \/ coverlet to gather metrics, and\ndanielpalme \/ ReportGenerator for generate human-readable reports.\nHow can set-up coverlet? I usually include coverlet.msbuild by MSBuild .targets Files - Visual Studio | Microsoft Docs.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 &lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt; &lt;Project&gt; &lt;PropertyGroup&gt; &lt;CollectCoverage&gt;true&lt;\/CollectCoverage&gt; &lt;CoverletOutputFormat&gt;cobertura&lt;\/CoverletOutputFormat&gt; &lt;CoverletOutput&gt;$(ArtifactsCoverageDir)\\$(MSBuildProjectName).xml&lt;\/CoverletOutput&gt; &lt;\/PropertyGroup&gt; &lt;ItemGroup&gt; &lt;PackageReference Include=&#34;coverlet.msbuild&#34; Version=&#34;$(CoverletMSBuildVersion)&#34; IsImplicitlyDefined=&#34;true&#34; PrivateAssets=&#34;all&#34; Publish=&#34;true&#34; \/&gt; &lt;\/ItemGroup&gt; &lt;\/Project&gt; For alternative ways to include coverlet into yout test project see also coverlet-coverage\/coverlet: Cross platform code coverage for .NET (github.com).\nHow can set-up ReportGenerator? In keeping with above to include ReportGenerator by MSBuild .targets Files - Visual Studio | Microsoft Docs.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 &lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt; &lt;Project&gt; &lt;ItemGroup&gt; &lt;PackageReference Include=&#34;ReportGenerator&#34; Version=&#34;$(ReportGeneratorVersion)&#34; IsImplicitlyDefined=&#34;true&#34; PrivateAssets=&#34;all&#34; Publish=&#34;true&#34; \/&gt; &lt;\/ItemGroup&gt; &lt;Target Name=&#34;GenerateCoverageReport&#34; AfterTargets=&#34;GenerateCoverageResultAfterTest&#34;&gt; &lt;ItemGroup&gt; &lt;CoverageFiles Include=&#34;$(ArtifactsCoverageDir)\\$(MSBuildProjectName).xml&#34; \/&gt; &lt;\/ItemGroup&gt; &lt;ReportGenerator ProjectDirectory=&#34;$(MSBuildProjectDirectory)&#34; ReportFiles=&#34;@(CoverageFiles)&#34; TargetDirectory=&#34;$(ArtifactsReportDir)\\$(MSBuildProjectName)\\Reports&#34; ReportTypes=&#34;Html;Latex&#34; HistoryDirectory=&#34;$(ArtifactsReportDir)\\$(MSBuildProjectName)\\History&#34; VerbosityLevel=&#34;Verbose&#34; \/&gt; &lt;\/Target&gt; &lt;\/Project&gt; Also this tool offer a various way to use it, you can find all ways onto official documentation ReportGenerator - converts coverage reports generated by coverlet.\nHow to wire-up all that? To make everything work we need to add another MSBuild file.\n1 2 3 4 5 6 7 8 9 10 11 12 &lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt; &lt;Project&gt; &lt;PropertyGroup&gt; &lt;VSTestLogger&gt;trx&lt;\/VSTestLogger&gt; &lt;VSTestResultsDirectory&gt;$(ArtifactsTestResultsDir)&lt;\/VSTestResultsDirectory&gt; &lt;\/PropertyGroup&gt; &lt;Import Project=&#34;CollectCoverage.targets&#34; \/&gt; &lt;Import Project=&#34;ReportGenerator.targets&#34; \/&gt; &lt;\/Project&gt; And include this into your test project, something like this\n1 2 3 4 5 6 7 8 9 &lt;Project Sdk=&#34;Microsoft.NET.Sdk&#34;&gt; &lt;PropertyGroup&gt; &lt;TargetFramework&gt;net5.0&lt;\/TargetFramework&gt; &lt;\/PropertyGroup&gt; &lt;Import Project=&#34;Tests.targets&#34; \/&gt; &lt;\/Project&gt; Now everything you are able to run dotnet test you will able to inspect and analyze something like this\nI think that is an amazing tool to understand at a glance which codes are covered and which not.\nAnd now, how I can put it into Azure DevOps pipeline? It would be nice if this report came was published into the Build pipeline report, don&rsquo;t you think? Maybe even include branch policies for it.\nWell that&rsquo;s possible by use Publish Code Coverage Results task, something like this:\n1 2 3 4 5 6 7 - task: PublishCodeCoverageResults@1 displayName: Publish Code Coverage Results inputs: codeCoverageTool: &#39;cobertura&#39; summaryFileLocation: &#39;$(Build.SourcesDirectory)\/artifacts\/TestResults\/$(_BuildConfig)\/Reports\/Summary\/Cobertura.xml&#39; continueOnError: true condition: always() We notice the summaryFileLocation argument, this means that we will push only one file to Azure DevOps why?\nOne unwrite note of Publish Code Coverage Results task or limitation, I don&rsquo;t know, is that the sum of covered lines, when we publish more reports, is take from the first file\nThis results in an unreliable result.\nTo fix that problem we can marge multiple reports into a summary reports so that can be publish it only one. One way to make it is the follow\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 &lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt; &lt;Project Sdk=&#34;Microsoft.NET.Sdk&#34; DefaultTargets=&#34;GenerateSummaryCoverageReport&#34; xmlns=&#34;http:\/\/schemas.microsoft.com\/developer\/msbuild\/2003&#34;&gt; &lt;PropertyGroup&gt; &lt;TargetFramework&gt;net5.0&lt;\/TargetFramework&gt; &lt;\/PropertyGroup&gt; &lt;UsingTask TaskName=&#34;ReportGenerator&#34; AssemblyFile=&#34;$(NuGetPackageRoot)reportgenerator\\$(ReportGeneratorVersion)\\tools\\$(TargetFramework)\\ReportGenerator.MSBuild.dll&#34; \/&gt; &lt;Target Name=&#34;GenerateSummaryCoverageReport&#34; DependsOnTargets=&#34;Restore&#34;&gt; &lt;ItemGroup&gt; &lt;CoverageFiles Include=&#34;$(ArtifactsCoverageDir)\\*.xml&#34; \/&gt; &lt;\/ItemGroup&gt; &lt;ReportGenerator ProjectDirectory=&#34;$(MSBuildProjectDirectory)&#34; ReportFiles=&#34;@(CoverageFiles)&#34; TargetDirectory=&#34;$(ArtifactsTestResultsDir)\\Reports\\Summary&#34; ReportTypes=&#34;Cobertura&#34; \/&gt; &lt;\/Target&gt; &lt;\/Project&gt; and run MSBuild project into the pipeline with\n1 2 3 - script: dotnet msbuild SummaryReportGenerator.proj \/p:Configuration=$(Configuration) name: GenerateCodeCoverageSummary displayName: Generate code coverage summary Once you&rsquo;ve done this the sum of covered lines on Build pipeline will true.\nThe greenfield approch. All above is fully automated into MsBullet from version 0.6.1.\nIf you are approaching a greenfield then you might find this getting started useful.\nIf, on the other hand, you are intent on using it in a brownfield and need some tips, leave a comment below.\nIf you need to share sensitive information feel free to contact me privately!\n","permalink":"https:\/\/binick.blog\/2021\/01\/02\/how-to-include-code-coverage-in-azure-devops-pipeline\/","summary":"<p>By code coverage, we mean the action of trying to measure how much of our code has been executed by our tests.\nThis sound like<\/p>\n\n\n<p><details >\n  <summary markdown=\"span\">TL;DR<\/summary>\n  <blockquote>\n<p>Untested code is a broken code.\nDefinitely a strong statement but true in a way, we don&rsquo;t always manage to get enough coverage.\nOften this happens because we don&rsquo;t have time, other times because despite having written tests we are not able to read the metrics.<\/p>","title":"How to include code coverage in Azure DevOps pipeline?"},{"content":"Sometimes we have been forced to work with JSON stored on table columns, it will have happened to you too!\nIn this post, I want to show you how to work with that using EntityFramework Core\ndotnet \/ efcore Clearly this is one of many possible ways.\nWe could talk for a long time about the choice to store JSON into RDBMS is a good or bad choice, but the intent of this post isn&rsquo;t making a rant.\nOk, well. First of all, take a look to JSON that we want to persist into a table column\nOur application has a requirement that makes it necessary to query the database with the name of the retailer that has stored in the JSON.\nThe retailer is the one who has the car we want to rent. The car is represented by the class\nThe Car entity has a property public string NameOfRetailer { get; } that is computed by the Computed columns functionality.\nWith this instruction efcore will inflate property with value returned by JSON_VALUE(Metadata, '$.Retailer.Name') expression, for more information about JSON_VALUE see at JSON_VALUE\nTo make it work, we need to persist the JSON into table column Metadata.\nWe can use the other useful Value conversions functionality of efcore.\nNow, after that model configurations we are able to resolve this simple query var car = await context.Cars.MaterializeAsync(car =&gt; car.NameOfRetailer == &quot;Car Auto Orvieto&quot;).ConfigureAwait(false); without materialize the entire dataset on the client. \ud83d\ude80\nIf you want to learn more you can find the sample on my github repo ef-core-json\nHappy coding! \ud83d\udc31\u200d\ud83d\udc64\n","permalink":"https:\/\/binick.blog\/2020\/10\/22\/sql-server-ef-core-json\/","summary":"<p>Sometimes we have been forced to work with JSON stored on table columns, it will have happened to you too!<\/p>\n<p>In this post, I want to show you how to work with that using <strong>EntityFramework Core<\/strong><\/p>\n\n  <div class=\"github-ref-container\">\n    <h2>\n      <svg version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\" x=\"0px\" y=\"0px\" viewBox=\"0 0 36 36\" enable-background=\"new 0 0 36 36\" xml:space=\"preserve\">\n        <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" fill=\"#191717\" d=\"M18,1.4C9,1.4,1.7,8.7,1.7,17.7c0,7.2,4.7,13.3,11.1,15.5\n          c0.8,0.1,1.1-0.4,1.1-0.8c0-0.4,0-1.4,0-2.8c-4.5,1-5.5-2.2-5.5-2.2c-0.7-1.9-1.8-2.4-1.8-2.4c-1.5-1,0.1-1,0.1-1\n          c1.6,0.1,2.5,1.7,2.5,1.7c1.5,2.5,3.8,1.8,4.7,1.4c0.1-1.1,0.6-1.8,1-2.2c-3.6-0.4-7.4-1.8-7.4-8.1c0-1.8,0.6-3.2,1.7-4.4\n          c-0.2-0.4-0.7-2.1,0.2-4.3c0,0,1.4-0.4,4.5,1.7c1.3-0.4,2.7-0.5,4.1-0.5c1.4,0,2.8,0.2,4.1,0.5c3.1-2.1,4.5-1.7,4.5-1.7\n          c0.9,2.2,0.3,3.9,0.2,4.3c1,1.1,1.7,2.6,1.7,4.4c0,6.3-3.8,7.6-7.4,8c0.6,0.5,1.1,1.5,1.1,3c0,2.2,0,3.9,0,4.5\n          c0,0.4,0.3,0.9,1.1,0.8c6.5-2.2,11.1-8.3,11.1-15.5C34.3,8.7,27,1.4,18,1.4z\" \/>\n      <\/svg>\n      <a href=\"https:\/\/github.com\/dotnet\" class=\"account\">dotnet<\/a>\n      \/\n      <a href=\"https:\/\/github.com\/dotnet\/efcore\" class=\"repo\">efcore<\/a>\n    <\/h2>\n  <\/div>\n\n\n<p>Clearly this is one of many possible ways.<\/p>\n<p>We could talk for a long time about the choice to store JSON into RDBMS is a good or bad choice, but the intent of this post isn&rsquo;t making a rant.<\/p>","title":"SQL Server, EF Core, JSON"},{"content":"","permalink":"https:\/\/binick.blog\/about-me\/","summary":"About me","title":"About me"},{"content":" MsBullet SDK is a set of MSBuild files that provide common build features of MSBuild SDK distributed through NuGet package.\nThe pillars on which MsBullet SDK is based are:\nControl and ownership The developer teams are owners of their repos and they should be feel free to use whatever tools they want.\nReusability of functionality Business value is the main goal. The functionality one team has developed can contribute to another&rsquo;s success.\n","permalink":"https:\/\/binick.blog\/projects\/msbullet\/","summary":"<figure>\n    <img loading=\"lazy\" src=\".\/icon.png\"\/> \n<\/figure>\n\n<p><a href=\"\/msbullet\"><img loading=\"lazy\" src=\"https:\/\/img.shields.io\/badge\/Docs-MsBullet-green\"><\/a><\/p>\n<p><a href=\"https:\/\/www.nuget.org\/packages\/MsBullet.Sdk\"><img loading=\"lazy\" src=\"https:\/\/img.shields.io\/nuget\/v\/msbullet.sdk\"><\/a><\/p>\n<p>MsBullet SDK is a set of MSBuild files that provide common build features of MSBuild SDK distributed through NuGet package.<\/p>\n<p>The pillars on which MsBullet SDK is based are:<\/p>\n<h3 id=\"control-and-ownership\">Control and ownership<\/h3>\n<p>The developer teams are owners of their repos and they should be feel free to use whatever tools they want.<\/p>\n<h3 id=\"reusability-of-functionality\">Reusability of functionality<\/h3>\n<p>Business value is the main goal.\nThe functionality one team has developed can contribute to another&rsquo;s success.<\/p>","title":"MsBullet"}]