Showing posts with label sdk. Show all posts
Showing posts with label sdk. Show all posts

Friday, August 31, 2018

Solving NETSDK1061 build errors

Microsoft has changed a lot in the last 10 years, especially since Satya Nadella took over, and not for the better in many ways. One of the ways they've changed is that they've gotten a lot faster, which on the surface sounds good. When you start digging into the consequences of that change however, it's not so great: one of the ways in which that faster development velocity is enabled is by skipping over things I find to be essential, like documentation.

Today, the documentation that's missing from Microsoft's websites and negatively impacting me is how to keep the version of your dotnetcore 2.x+ SDKs "sticky" during your Visual Studio desktop builds and automated VSTS builds when Microsoft upgrades their SDKs. The very annoying thing is that Microsoft is going **so fast** that they're including beta and prerelease builds WITH VISUAL STUDIO!! That's a big no no as far as impacting one's customers in my book. The consequence of this is that you can upgrade Visual Studio, and what built with the previous version will no longer build with the current version. This results in builds errors with code:

NETSDK1061: The project was restored using Microsoft.NETCore.App version 2.1.3, but with current settings, version 2.1.3-servicing-26724-03 would be used instead. To resolve this issue, make sure the same settings are used for restore and for subsequent operations such as build or publish. Typically this issue can occur if the RuntimeIdentifier property is set during build or publish but not during restore. For more information, see https://aka.ms/dotnet-runtime-patch-selection.

Following the link in the error message, you're taken to documentation that tells you nothing useful about how to actually solve this error. Instead, you get to Google around and if you happen to find the right set of keywords and stumble across this documentation and read it **** VERY CAREFULLY **** you'll find that you need to make use of the "RuntimeFrameworkVersion" property that has to be specified in the .csproj project file of your dotnet core project, and you have to set that to the version you want to actually use for building your dotnet core project, in addition to a <PackageReference> element that looks similar to the following:

<PackageReference Update="Microsoft.NETCore.App" Version="2.1.2" />

The version in the above <PackageReference> element should match what you have in your <RuntimeFrameworkVersion> element.

Wednesday, March 30, 2016

Running and debugging Azure WebJobs locally on your development machine

Check out this article: https://github.com/Azure/azure-webjobs-sdk/wiki/Running-Locally

It shows you how to locally run and debug Azure WebJobs, which as it turns out is extremely handy because you can interact with all the Queues, Tables, Blobs etc as you normally would and get a full debugging environment.

Sunday, February 28, 2016

Properly invoking scheduled WebJobs

Recently we've found the need to start using Scheduled Azure WebJobs. However, the examples out there are all gargbage, even in the case where you can find an actual example using a scheduled WebJob rather than a continuous WebJob. So, for the benefit of anyone interested, including future me, here's the proper way to invoke a Scheduled WebJob in the entry point of the WebJobs assembly:

    /// <summary>
    /// The main entry point to the scheduled webjobs.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Main entry point for the scheduled webjobs
        /// </summary>
        public static void Main()
        {
            IKernel kernel = new StandardKernel();

            kernel.Load(new ServicesScheduledWebJobsNinjectModule());

            var jobHostConfiguration = new JobHostConfiguration
            {
                JobActivator = new ServicesScheduledWebJobsActivator(kernel),
                DashboardConnectionString = ConfigurationManager.ConnectionStrings["AzureWebJobsDashboard"].ConnectionString,
                StorageConnectionString = ConfigurationManager.ConnectionStrings["AzureWebJobsStorage"].ConnectionString,
            };

            var host = new JobHost(jobHostConfiguration);

            // Must ensure that we call host.Start() to actually start the job host. Must do so in
            // order to ensure that all jobs we manually invoke can actually run.
            host.Start();

            // The following code will invoke all functions that have a 'NoAutomaticTriggerAttribute'
            // to indicate that they are scheduled methods.
            foreach (MethodInfo jobMethod in typeof(Functions).GetMethods().Where(m => m.GetCustomAttributes<NoAutomaticTriggerAttribute>().Any()))
            {
                try
                {
                    host.CallAsync(jobMethod).Wait();
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("Failed to execute job method '{0}' with error: {1}", jobMethod.Name, ex);
                }
            }
        }
    }

What the above does is the following:

  • Configures the JobHost to use a dependency injection container via a custom IJobActivator implementation that, in our case, uses the Ninject dependency injection container.
  • Configures the JobHost with a custom configuration so that we can control various items, including the connection strings for the dashboard and jobs storage.
  • Starts the JobHost. This bit is important, because all the other examples out there neglect that this needs to be done.
  • Dynamically resolves all schedulable methods that should be invoked, using the NoAutomaticTriggerAttribute built in to the WebJobs SDK. This attribute is used internally by the SDK to determine which methods need to be invoked manually (i.e. on demand) rather than by a continuous invocation used by Continous WebJobs.

Monday, January 18, 2016

Enabling manipulation of Azure Active Directory groups through Web Applications via the Azure Graph SDK

In your application(s) (plural if you're using a web / native application delegating to a Web Services API which is doing the actual work), you'll need to go into their pages in the Azure Active Directory management page. Once there, edit the permissions of the applications to include the following:

Under the delegated-to application:

  • Under "Application Permissions", select:
    • Read and write domains
    • Read and write directory data
    • Read directory data
  • Under "Delegated Permissions", select:
    • Read and write directory data
    • Read and write all groups
    • Read all groups
    • Access the directory as the signed-in user
    • Read directory data
Under the top-level application:

  • Under "Delegated permissions", select:
    • Read and write directory data 
    • Read and write all groups 
    • Read all groups 
    • Access the directory as the signed-in user 
    • Read directory data