Resolving service for IHttpClientFactory fails on Azure Function - c#

I am trying to inject IHttpClientFactory service on Azure Function v3, but I keep getting the following erorr saying resolving a service failed.
I use azure-functions-core-tools#v3 to run Azure Function locally.
[2/14/2020 5:45:19 PM] Executed 'Foo' (Failed, Id=24489b3b-af99-417e-b175-443b76c241d5)
[2/14/2020 5:45:19 PM] Microsoft.Extensions.DependencyInjection.Abstractions: Unable to resolve service for type 'System.Net.Http.IHttpClientFactory' while attempting to activate 'MyFunction.Function.Foo'.
I have a startup class that is supposed to inject a service for IHttpClientFactory.
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
namespace MyFunction
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
}
}
}
And below is an azure function class that uses injected service of IHttpClientFactory to create a HTTP client and send a GET request to a server.
using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace MyFunction.Function
{
public class Foo
{
private readonly HttpClient httpClient;
public Scrape(IHttpClientFactory httpClientFactory)
{
httpClient = httpClientFactory.CreateClient();
}
[FunctionName("Foo")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
var result = await httpClient.GetAsync("https://google.com");
var data = await result.Content.ReadAsStringAsync();
return new OkObjectResult(data);
}
}
}
Am I missing something?

It looks like your startup.cs class is missing it's assembly reference?
[assembly: FunctionsStartup(typeof(MyFunction.Startup))]
Try adding that to the startup class. Add it just after your using statements at the top, and before any namespace declaration.
Also, most examples I have seen show the client actually created during function execution, not in the default constructor.
using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace MyFunction.Function
{
public class Foo
{
private readonly HttpClient httpClient;
public Scrape(IHttpClientFactory httpClientFactory)
{
factory = httpClientFactory;
}
[FunctionName("Foo")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
HttpClient httpClient = factory.CreateClient();
var result = await httpClient.GetAsync("https://google.com");
var data = await result.Content.ReadAsStringAsync();
return new OkObjectResult(data);
}
}
}

Related

xUnit testing controller with error when instantiating JWT token provider

I have a controller in my WebAPI (not MVC or Core) using .Net 4.8 that I'm trying to test with xUnit.
Before I proceed, the way it is setup may not be correct for unit testing, but it is what I have been given and I don't know any better at this stage, any pointers in this regard is welcome.
The main problem in the controller is the immediate declaration/instantiation of ApiOAuthProvider. As it creates the object, it in-turn does an immediate declaration/instantiation of JwtTokenProvider. This is where the error occurs, inner exception:
Message "Could not load file or assembly
'System.Configuration.ConfigurationManager, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot
find the file specified."
But I'm jumping ahead I'll show the code
Controller:
using System.Net;
using System.Net.Http;
using System.Web.Http;
using TA.Services.BL.BusinessLogic;
using TA.Services.WebAPI.Providers;
using TA.Services.DTO.DTO;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
using TA.Services.BL.Interface;
namespace TA.Services.WebAPI.Controllers
{
public class AccountsController : ApiController
{
private readonly ApiOAuthProvider _jwtTokenProvider = new ApiOAuthProvider();
private readonly ICommonBL _commonBL;
private readonly ISystemSettingsBL _systemSettingsBL;
public AccountsController(ICommonBL commonBL, ISystemSettingsBL systemSettingsBL)
{
_commonBL = commonBL;
_systemSettingsBL = systemSettingsBL;
}
...
// GET: JwtToken
[HttpPost]
//[EnableCors("*", "*", "*")]
public JObject Token(User loginUserCredentials)
{
// first check the user name & password is valid one before generating token for that user.
var user = _commonBL.GetUserInformation(loginUserCredentials.UserName);
var accessToken = _jwtTokenProvider.GenerateToken(user);
return accessToken;
}
}
}
ApiOAuthProvider:
namespace TA.Services.WebAPI.Providers
{
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Web.Http.Cors;
using TA.Services.DTO.DTO;
using static TA.Services.WebAPI.Providers.JWTHelper;
[EnableCors("*", "*", "*")]
public class ApiOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly JwtTokenProvider _jwtTokenProvider = new JwtTokenProvider();
[EnableCors("*", "*", "*")]
public JObject GenerateToken(User userDetail)
{
...
return tokenResponse;
}
public static AuthenticationProperties CreateProperties(string userName, Status apiData)
{
...
return new AuthenticationProperties(data);
}
}
}
JwtTokenProvider:
namespace TA.Services.WebAPI.Providers
{
using System;
using System.Configuration;
using System.Security.Claims;
using System.Text;
using System.Web.Configuration;
using System.Web;
using Microsoft.Owin.Security;
using TA.Services.BL.Interface;
using TA.Services.DTO.DTO;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
public class JwtTokenProvider : ISecureDataFormat<AuthenticationTicket>
{
private static string plainTextSecurityKey = ((MachineKeySection)ConfigurationManager.GetSection("system.web/machineKey")).ValidationKey;
private readonly Microsoft.IdentityModel.Tokens.SymmetricSecurityKey _signingKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(plainTextSecurityKey));
private readonly IAuditsBL _auditsBL;
public string Protect(AuthenticationTicket data)
{
var signedAndEncodedToken = string.Empty;
...
return signedAndEncodedToken;
}
public AuthenticationTicket Unprotect(string signedAndEncodedToken)
{
ClaimsIdentity idenity = null;
...
return new AuthenticationTicket(idenity, new AuthenticationProperties());
}
}
}
My xUnit test class:
using Moq;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Principal;
using System.Web.Http;
using TA.Services.BL.Interface;
using TA.Services.DTO.DTO;
using TA.Services.WebAPI.Controllers;
using TA.Services.WebAPI.Providers;
using Xunit;
namespace TA.Services.WebAPI.Tests.Controllers
{
public class AccountsControllerTests : BaseUnitTest
{
private readonly Mock<ICommonBL> _commonBLMock;
private readonly Mock<ISystemSettingsBL> _systemSettingsBLMock;
private readonly AccountsController _accountsController;
public AccountsControllerTests()
{
_commonBLMock = new Mock<ICommonBL>();
_systemSettingsBLMock = new Mock<ISystemSettingsBL>();
_accountsController = new AccountsController(_commonBLMock.Object, _systemSettingsBLMock.Object);
}
...
}
}
The exception occurs here in JwtTokenProvider:
private readonly Microsoft.IdentityModel.Tokens.SymmetricSecurityKey _signingKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(plainTextSecurityKey));
StackTrace:
at TA.Services.WebAPI.Providers.JwtTokenProvider..ctor() in C:\TA\Repos\April 20 2021\TADev\Service\TA.Services\TA.Services.WebAPI\Providers\JwtTokenProvider.cs:line 19
at TA.Services.WebAPI.Providers.ApiOAuthProvider..ctor() in C:\TA\Repos\April 20 2021\TADev\Service\TA.Services\TA.Services.WebAPI\Providers\ApiOAuthProvider.cs:line 23
at TA.Services.WebAPI.Controllers.AccountsController..ctor(ICommonBL commonBL, ISystemSettingsBL systemSettingsBL) in C:\TA\Repos\April 20 2021\TADev\Service\TA.Services\TA.Services.WebAPI\Controllers\AccountsController.cs:line 27
at TA.Services.WebAPI.Tests.Controllers.AccountsControllerTests..ctor() in C:\TA\Repos\April 20 2021\TADev\Service\TA.Services\Testing\TA.Services.WebAPI.Tests\Controllers\AccountsControllerTests.cs:line 26
Sub-questions:
Maybe I'm going down the wrong path, however should I mock ApiOAuthProvider, in order to do that I need to inject it, in order to do that, I need to create an interface and registry it as a service, but this doesn't sound right.
Do I just need to create a valid token.
Maybe it really can't find the System.Configuration.ConfigurationManager
Main Question: How should I go about resolving this?
Note: The application works just fine outside of this test, under normal execution.
[Update] Changed controller have ApiOAuthProvider injected
public class AccountsController : ApiController
{
private readonly ApiOAuthProvider _jwtTokenProvider;
private readonly ICommonBL _commonBL;
private readonly ISystemSettingsBL _systemSettingsBL;
public AccountsController(ApiOAuthProvider jwtTokenProvider, ICommonBL commonBL, ISystemSettingsBL systemSettingsBL)
{
_commonBL = commonBL;
_systemSettingsBL = systemSettingsBL;
_jwtTokenProvider = jwtTokenProvider;
}
Added ApiOAuthProvider to services in startup:
services.AddSingleton<ApiOAuthProvider>();
Changed test script:
public class AccountsControllerTests : BaseUnitTest
{
private readonly Mock<ApiOAuthProvider> _apiOAuthProviderMock;
private readonly Mock<ICommonBL> _commonBLMock;
private readonly Mock<ISystemSettingsBL> _systemSettingsBLMock;
private readonly AccountsController _accountsController;
public AccountsControllerTests()
{
_apiOAuthProviderMock = new Mock<ApiOAuthProvider>();
_commonBLMock = new Mock<ICommonBL>();
_systemSettingsBLMock = new Mock<ISystemSettingsBL>();
_accountsController = new AccountsController(_apiOAuthProviderMock.Object, _commonBLMock.Object, _systemSettingsBLMock.Object);
}
...
Debugged the test and it kept going until it got to the same error. Doesn't seem to mock very well without an interface.
[Update End]

Add telemetry in http trigger function in .net core 3.1

I have added the telemetry in Http trigger function by adding package Microsoft.ApplicationInsights" Version="2.17.0" to view the logs in application insight.
private readonly TelemetryClient _telemetry;
public GoogleAuth(ShoppingContentService service, int maxListPageSize,TelemetryConfiguration telemetryConfiguration)
{
this.service = service;
this.maxListPageSize = maxListPageSize;
this._telemetry = new TelemetryClient(telemetryConfiguration);
}
and I am using this telemetry inside my http trigger function .
_telemetry.TrackTrace($"[GoogleProductData]: Request body:{data}");
But I am getting this error.
An unhandled host error has occurred.
[2021-06-17T13:08:55.752Z] Microsoft.Extensions.DependencyInjection.Abstractions: Unable to resolve service for type 'Google.Apis.ShoppingContent.v2_1.ShoppingContentService' while attempting to activate 'ShoppingSamples.Content.GoogleAuth'.
Pls follow this tutorial and using Microsoft.Azure.WebJobs.Logging.ApplicationInsights instead. This is recommended by official document. This is my testing code( just create a new http trigger function in visual studio)
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Extensibility;
namespace FunctionApp1
{
public class Function1
{
private readonly TelemetryClient telemetryClient;
/// Using dependency injection will guarantee that you use the same configuration for telemetry collected automatically and manually.
public Function1(TelemetryConfiguration telemetryConfiguration)
{
this.telemetryClient = new TelemetryClient(telemetryConfiguration);
}
[FunctionName("Function1")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
}
and adding APPINSIGHTS_INSTRUMENTATIONKEY to local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"APPINSIGHTS_INSTRUMENTATIONKEY": "instrument_key_here"
}
}

Microsoft Azure Functions - Setting up HttpTrigger / Binding to Table Storage for input - C#

I'm attempting to developer an Azure Function App which is triggered by a Http Request and takes the information on said request and added it into a Table in Table Storage. I developed in the portal and have been trying to redo the whole thing locally and publish it to Azure but running into issues with triggering the function and actually having it add to the Table I want it to add too... any help would be really appreciated!
This is what I have so far:
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Http;
namespace LookUpService
{
public static class AddConnectionDetails
{
[FunctionName("AddConnectionDetails")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequest req, ILogger log, ICollector<SocietyConnection> lookupTable)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
lookupTable.Add(new SocietyConnection()
{
PartitionKey = data.PartitionKey,
RowKey = data.RowKey,
Connection = data.Connection,
Organisation = data.Organisation
});
return new OkObjectResult($"{data.Organisation}({data.PartitionKey}) {data.RowKey} added to LookUp Table Storage");
}
public class SocietyConnection
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Connection { get; set; }
public string Organisation { get; set; }
}
}
}
It seems that theres no actual trigger on the function when i've published it and it isnt connecting to the table I want to put stuff into...
Let me know if I've not made anything clear enough!
First, if you develop code on local, you should bebug first. if the function works fine, then publish this function app to azure.
For your requirement, please use below code, it works fine on my side:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
namespace FunctionApp49
{
public class LogEntity : TableEntity
{
public string OriginalName { get; set; }
}
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[Table("AzureWebJobsHostLogscommon")] CloudTable cloudTable,
ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
TableQuery<LogEntity> rangeQuery = new TableQuery<LogEntity>().Where(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal,
"FD2"),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThan,
"t")));
// Execute the query and loop through the results
foreach (LogEntity entity in
await cloudTable.ExecuteQuerySegmentedAsync(rangeQuery, null))
{
log.LogInformation(
$"{entity.PartitionKey}\t{entity.RowKey}\t{entity.Timestamp}\t{entity.OriginalName}");
}
return new OkObjectResult("111111111111111111");
}
}
}
Have a look of this doc:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-table?tabs=csharp#cloudtable

Azure Functions unit-testing errors (TimerTrigger. HttpFunction)

I am currently following this guide (https://learn.microsoft.com/en-us/azure/azure-functions/functions-test-a-function) for adding testing to my Azure Functions application.
Currently I have built out 8 Azure Functions which all work well, I have also added a Functions.Tests project and referenced the Azure Functions project within it.
Here is what the Functions.Tests currently look like.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Functions.Tests
{
public class FunctionsTests
{
private readonly ILogger logger = TestFactory.CreateLogger();
[Fact]
public async void Http_trigger_should_return_known_string()
{
var request = TestFactory.CreateHttpRequest("name", "Bill");
var response = (OkObjectResult)await HttpFunction.Run(request, logger);
Assert.Equal("Hello, Bill", response.Value);
}
[Theory]
[MemberData(nameof(TestFactory.Data), MemberType = typeof(TestFactory))]
public async void Http_trigger_should_return_known_string_from_member_data(string queryStringKey, string queryStringValue)
{
var request = TestFactory.CreateHttpRequest(queryStringKey, queryStringValue);
var response = (OkObjectResult)await HttpFunction.Run(request, logger);
Assert.Equal($"Hello, {queryStringValue}", response.Value);
}
[Fact]
public void Timer_should_log_message()
{
var logger = (ListLogger)TestFactory.CreateLogger(LoggerTypes.List);
TimerTrigger.Run(null, logger);
var msg = logger.Logs[0];
Assert.Contains("C# Timer trigger function executed at", msg);
}
}
}
However I am getting the following errors within FunctionsTests.cs
I have tried all the suggested fixes from Visual Studio and checked resources online but with no luck. Perhaps I am missing a reference? I'm not sure as I have followed the guide word for word.
Example Azure Function used:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Exemplar
{
public static class getCase
{
[FunctionName("getCase")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "v1/case/caseId")] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
}
Assuming provided project that contains the function is referenced, the test simply needs to arrange and exercise the target function as shown in the linked example
[Fact]
public async Task getCase_should_return_known_string()
{
var request = TestFactory.CreateHttpRequest("name", "Bill");
var response = (OkObjectResult)await getCase.Run(request, logger);
Assert.Equal("Hello, Bill", response.Value);
}
[Theory]
[MemberData(nameof(TestFactory.Data), MemberType = typeof(TestFactory))]
public async Task getCase_should_return_known_string_from_member_data(string queryStringKey, string queryStringValue)
{
var request = TestFactory.CreateHttpRequest(queryStringKey, queryStringValue);
var response = (OkObjectResult)await getCase.Run(request, logger);
Assert.Equal($"Hello, {queryStringValue}", response.Value);
}
Also avoid using async void. Refactor those tests to use async Task instead.
Seems to me it's missing a reference to your azure functios project, make sure you've added the reference by:
right clicking your test project
select the menu Add
select Reference
select the projects tab (left menu), then mark the checkbox of your function project
click ok

Using MySqlDatabase (MySql.Data.MySqlClient) on Azure Functions v2 - "Unable to resolve service"

I have created an Azure Functions app ~v2 project that uses the MySql.Data.MySqlClient dependency.
The project is setup to also use the SwashBuckle library to create a callable API.
When I execute my project from my local settings, it works fine. Yet, when I publish the Functions app to our Azure server and try testing the function there, I get this error:
System.InvalidOperationException : Unable to resolve service for type
'MyFunctionApp.MySqlDatabase' while attempting to activate
'MyFunctionApp.PostsService'.
at
Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider
sp,Type type,Type requiredBy,Boolean isDefaultParameterRequired)
...
My StartUp.cs:
using System;
using System.Reflection;
using AzureFunctions.Extensions.Swashbuckle;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.DependencyInjection;
using MyFunctionApp;
[assembly: WebJobsStartup(typeof(SwashBuckleStartup))]
namespace MyFunctionApp
{
internal class SwashBuckleStartup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
ConfigureServices(builder.Services);
builder.AddSwashBuckle(Assembly.GetExecutingAssembly());
}
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<MySqlDatabase>(_ => new MySqlDatabase(Environment.GetEnvironmentVariable("MyFunctionApp-DbConn")));
}
}
}
My MySqlDatabase.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
namespace MyFunctionApp
{
public class MySqlDatabase : IDisposable
{
public MySqlConnection Connection;
public MySqlDatabase(string connectionString)
{
Connection = new MySqlConnection(connectionString);
this.Connection.Open();
}
public void Dispose()
{
Connection.Close();
}
}
}
Here's the service I'm calling that's throwing the error mentioned above (PostsService.cs):
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Net;
using MySql.Data.MySqlClient;
namespace MyFunctionApp
{
public class PostsService
{
private readonly MySqlDatabase _MySqlDatabase;
public PostsService(MySqlDatabase mySqlDatabase)
{
_MySqlDatabase = mySqlDatabase;
}
[FunctionName("InsertIntoPost")]
public async Task<IActionResult> InsertIntoPost(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] PostClassObject request,
ILogger log)
{
var cmd = _MySqlDatabase.Connection.CreateCommand() as MySqlCommand;
cmd.CommandText = #"INSERT INTO PostsTable(ID) VALUES (12345)";
int rowCount = await cmd.ExecuteNonQueryAsync();
Console.WriteLine(String.Format("Number of rows inserted={0}", rowCount));
return (ActionResult)new OkObjectResult(1);
}
}
}
I ended up separating my StartUp.cs into two files. Now everything works!
WebJobsStartup.cs:
using AzureFunctions.Extensions.Swashbuckle;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using System.Reflection;
using MyFunctionApp;
[assembly: WebJobsStartup(typeof(WebJobsStartup))]
namespace MyFunctionApp
{
public class WebJobsStartup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
builder.AddSwashBuckle(Assembly.GetExecutingAssembly());
}
}
}
MyFunctionAppStartUp.cs:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using System;
[assembly: FunctionsStartup(typeof(MyFunctionApp.MyFunctionAppStartup))]
namespace MyFunctionApp
{
public class MyFunctionApp : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient<MySqlDatabase>((s) =>
{
return new MySqlDatabase(Environment.GetEnvironmentVariable("MyFunctionApp-DbConn"));
});
builder.Services.AddSingleton<ServiceQueries>();
}
}
}

Categories

Resources