I'm working on an API for an Azure Static Web App. The web app is implemented in Angular (although that isn't important for this question), and the API is implemented in C# (NET 6). Deployment to Azure is via a GitHub action.
I can create an HTTP trigger API endpoint that works fine, like so:
public static class Tester
{
[FunctionName("Tester")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "v1/tester")] HttpRequest req,
ILogger log)
{
return new OkObjectResult("Hello World");
}
}
I'm also able to access this directly via the SWA URL: https://<sitename>.azurestaticapps.net/api/v1/tester.
However, as soon as I add a reference to an Azure storage NuGet package to the project file (specifically Microsoft.Azure.WebJobs.Extensions.Storage.Blobs), making no other changes to the code, the API endpoint no longer works once deployed (although it will work locally).
On deploying the code with that package referenced in the .csproj, hitting the API endpoint gives a 503 status code with the response:
Function host is not running.
I enabled Application Insights for this static web app, and a CryptographicException is being thrown on startup:
An error occurred while trying to encrypt the provided data. Refer to the inner exception for more information. For more information go to http://aka.ms/dataprotectionwarning Could not find any recognizable digits.
(The link in the message doesn't go anywhere useful).
I'm presuming this has something to do with the AzureWebJobsStorage setting, which cannot be set in an Azure Static Web App (for whatever reason).
Based on all of the above, it would seem that using Azure storage from within a static web app C# function is verboten. However, I can't find that stated explicitly online anywhere. Has anybody got this kind of thing to work?
I removed the following nuget packages to make it working:
Microsoft.Azure.EventGrid
Microsoft.Azure.WebJobs.Extensions.EventGrid
I decomposed my http functions to a separate project because SWA does not support the EventTriggers right now.
Related
I got a system in Azure cloud which has a docker and each pod in the docker is a different service implemented with c# .Net Core. One of these services is a gRPC service which is a file service and every other service who want to access a file are using an SDK which access that service directly and it allows to access the requested file. The SDK is a nuget which every service adds to its references.
A flow example: Service A => invoke a method from SDK => Calls file service which access a file => return a response to the SDK => return a response to service A.
My desired behavior: I want to identify in the SDK the service itself which invokes the SDK's method. I can't use a simple input like just passing a string parameter because it's important to know the true service and I can't risk someone sending wrong information.
this is a pseudo code of what I need:
//this is an SDK method
public string GetSomeValueFromFile(string fileName)
{
string invokingService = GetCurrentService();
...
...
}
And the question is how to implement this GetCurrentService() method since I have no idea where to start
I am working on an email program for a WordPress WooCommerce store. I have added a webhook into the WooCommerce settings in order to hit a C# WebAPI application that I have created. I am trying to get run an email process every time an order is created.
I created an API controller with that accepts the JSON data that is sent over from WooCommerce, and when testing it locally from a Postman request, the controller is hit no problem.
I am trying to publish the application on Azure, and when I do, I am getting a 400 error from both the WooCommerce settings as well as any Postman requests.
I have tried setting
<system.webServer>
<httpErrors existingResponse="PassThrough"/>
</system.webServer>
in the web.config file, which then returned a 502 error from Postman, but still the same error on the WooCommerce webhook side.
I also tried re-deploying which did not work either.
I am able to view the homepage as well as the API controller link on the standard MVC homepage/menu view.
The controller is a standard API controller inheriting from the APIController class:
public class OrdersController : ApiController
and it contains one method, ProcessOrders, with an [HttpGet, HttpPost] attribute on it, and a route of /api/orders/callback.
The controller is responsible for inserting the payload from the webhook into the database and then it uses some other classes email out some specific information about the product.
Is there some kind of setting that needs to be set in the Azure portal or on the web.config file? I am not very experienced with Azure so I am not too familiar if there is anything else that needs to be done for this.
Azure Information
I am deploying to azure from quick publish inside Visual Studio
A Pay-As-You-Go resource group
.Net Framework version 4.7
Remote debugging enabled
Web App app service
The only App service setting is WEBSITE_NODE_DEFAULT_VERSION set to 6.9.1
I have tried both Release and Debug configurations, the connection is valid when trying the Validate Connection option inside configuration, the File Publish Options are all unchecked (Remove additional files at destination, precompile during publishing, exclude files from app_data folder) and the publish works fine, and the app is accessible, except for the api controller.
The project is built as a .Net framework version 4.6.1 with Web API.
Thanks in advance for any help!
Edit
I have removed the parameter that was part of the original method that is being hit by the API, and I am now getting the error of No HTTP resource was found that matches the request URI. I have tried changing the Route data annotation as well as just making it HttpGet to see if it was accessible, and it is not working. I created a second action on the controller just to test returning a string, and that worked without problem, so I am not sure why it is not accessible. The intro to the method is as follows:
[HttpGet]
[Route("api/orders/callback")]
public string Callback() { return "Test"; }
I also updated this method to try just returning a simple string and it does not work. I also adjusted the second test method to accept a string POSTed to it and it is returning The requested resource does not support http method 'POST'.
This method looks like the following:
[HttpPost]
[Route("api/orders/new")]
public string SecondCallback(string payload) {
return payload;
}
I am trying to get my Web API 2 up and running on an Azure App Service. It works fine on my machine, on IIS 10, with the following tracing added, from the package Microsoft.AspNet.WebApi.Tracing:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableSystemDiagnosticsTracing();
SystemDiagnosticsTraceWriter traceWriter = config.EnableSystemDiagnosticsTracing();
traceWriter.IsVerbose = true;
traceWriter.MinimumLevel = TraceLevel.Debug;
config.Services.Add(typeof(ITraceWriter), new TextFileTracer());
This works fine on my dev machine, but I get the error
The service type ITraceWriter is not supported.
as soon as I publish to Azure. I thought a modern ASP.NET app was supposed to be self contained, and not rely on services being present or configured on the host, and a very up to date host at that. Why is this happening?
According to your description, I tested your code on my Web API application and I got the server error as follows on my local side.
The service type ITraceWriter is not supported.
Parameter name: serviceType
As mentioned in this official document about setting the Trace Writer:
To enable tracing, you must configure Web API to use your ITraceWriter implementation. You do this through the HttpConfiguration object, as shown in the following code:
config.Services.Replace(typeof(ITraceWriter), new TextFileTracer());
Only one trace writer can be active. By default, Web API sets a "no-op" tracer that does nothing. (The "no-op" tracer exists so that tracing code does not have to check whether the trace writer is null before writing a trace.)
After replacing ITraceWriter service with the TextFileTracer instance, I could make it work as expected both on my side and Azure.
Is there an event raised the moment a website is published and updated?
I've tried Application_End in global.asax but that event does not seem to be raised.
I suggest to use both Kudu and Microsoft ASP.NET WebHooks preview.
Kudu is the engine behind git deployments, WebJobs, and various other features in Azure Web Sites (Kudu source is on GitHub)
With Kudu, Azure Web Sites have a support for web hooks. There is an event "PostDeployment" that will be invoked whenever a deployment is complete with the result of that deployment.
Microsoft ASP.NET WebHooks preview provides a common model for receiving and processing WebHooks from any number of WebHook providers includign support for Kudu (Azure Web App Deployment).
So you may use Kudu WebHooks to get notified when an update has been deployed. (But that will require using Git Deploy instead of other ways to publish your web site).
Here is the way to do it :
First Install the Microsoft.AspNet.WebHooks.Receivers.Azure Nuget package.
The, Add these two lines to the WebApiConfig.Register method:
config.InitializeReceiveKuduWebHooks();
config.InitializeReceiveAzureAlertWebHooks();
Then Add a handler :
public class KuduWebHookHandler : WebHookHandler
{
public KuduWebHookHandler()
{
Receiver = "kudu";
}
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
// Convert to POCO type
KuduNotification notification = context.GetDataOrDefault<KuduNotification>();
// Get the notification message
string message = notification.Message;
// Get the notification author
string author = notification.Author;
return Task.FromResult(true);
}
}
Then configure a secret that can validates that the WebHook requests indeed come from Kudu.
Use high-entropy values such as a SHA256 hash or similar, which you can get from http://www.freeformatter.com/hmac-generator.html. Also, set them through the Azure Portal instead of hard-coding them in the Web.config file
Also, set them through the Azure Portal instead of hard-coding them in the Web.config file.
There is a more complete Post on the subject here (http://blogs.msdn.com/b/webdev/archive/2015/10/04/receive-webhooks-from-azure-alerts-and-kudu-azure-web-app-deployment.aspx)
Hope this helps
Best regards
Stéphane
I figured it out. In the Application_Start event I bind
RoleEnvironment.Stopping += RoleEnvironmentStopping;
private void RoleEnvironmentStopping(object sender, RoleEnvironmentStoppingEventArgs e)
{
// do something ...
}
I have constructed an API using webapi2.2.
When I deploy the API to Azure I get the Service Unhealthy Message...when I check the logs of my API the log gives the error message
"Boot strapping failed: executing 'WebApiConfig.Register' caused an
exception: 'Parameter count mismatch.'.
The Application Start function is below
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
And my WebApiConfig.cs has the following:
public static void Register(HttpConfiguration config)
{
config.EnableCors();
config.Formatters.JsonFormatter.
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));.......
Another question here: The api implements its own Security mechanism (I used the following as a reference http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/). Would this implementation work in Azure or would you have to make use of the x-zumo header authorisation mechanism?
I found the resolution to this - I believe that the problem is caused by the fact that I have another mobile services app running in my Azure account. That app was built awhile ago - early 2015 and used the register procedure with no parameters
public static void Register(){.....}
I think that this may have confused the service operation (the fact that one app has a register without parameters and the other has a register with one parameter). To resolve the issue with my new app I removed the config parameter, and build the config settings in the register function see below
public static void Register()
{
ConfigOptions options = new ConfigOptions();
HttpConfiguration config = ServiceConfig.Initialize(new ConfigBuilder(options));
config.EnableCors();.....
Remember though you will need access to the using Microsoft.WindowsAzure.Mobile.Service namespace...this can be obtained by installing the nuget package WindowsAzure.MobileServices.Backend
Hope this helps someone who has similar problems