Blazor Web Assembly Dynatrace integration - blazor-webassembly

We were previously using server side Blazor, with Dynatrace integration using the Dynatrace RUM. Now we are using Blazor Web Assembly (wasm), and I am not finding any examples online in regards to best practices for implementation.
This is our code for the Blazor server side implementation
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//Code removed for brevity
app.UseHttpsRedirection();
app.UseDynatraceRUM(Configuration["Dynatrace:ApiEndpoint"], Configuration["Dynatrace:ApiToken"], Configuration["Dynatrace:ApplicationId"], true);
app.UseStaticFiles();
//Code removed for brevity
}
I have tried finding ways to add the middleware to the blazor wasm, but not sure if we are better off with a JS only approach, as WebAssemblyHostBuilder does not provide the same extension methods as IApplicationBuilder?

Related

Putting Azure Application Insights in Shared Project and writing logs to it using Serilog

I have three projects inside a visual studio solution.
One is an ASP.NET MVC5 website called Mat2, the other is the Web API project called Mat2.API and the third one is a shared C# project called Mat2.Common
I am using Azure Application Insights inside the website and API projects. The configuration code and files/keys related to Azure Application Insights are placed inside both of these projects.
Before I go to my question, I would like to mention that I am using Serilog for logging. I have created my own Logger class and it is placed inside the Mat2.Common project.
Here is the code for it:
public class Logger
{
private static readonly ILogger logger;
static Logger()
{
logger = new LoggerConfiguration()
.Enrich.WithUserName(anonymousUsername: "Not Authenticated")
.Enrich.FromLogContext()
.Enrich.With(new ThreadEnrich())
.Enrich.WithMachineName()
.Enrich.WithHttpRequestId()
.Enrich.WithHttpRequestNumber()
.Enrich.WithHttpRequestClientHostIP()
.Enrich.WithHttpRequestType()
.Enrich.WithHttpRequestRawUrl()
.Enrich.WithMvcRouteData()
.Enrich.WithExceptionDetails(
new DestructuringOptionsBuilder()
.WithDefaultDestructurers())
.WriteTo.RollingFile(new JsonFormatter(),
HttpContext.Current.Server.MapPath($"~/logs/log-.json"),
LogEventLevel.Debug,
fileSizeLimitBytes: 655360)
.CreateLogger();
}
public static void LogInformation(string info, object[] data = null)
{
logger.Information(info, data);
}
public static void LogDebug(string debug, object[] data = null)
{
logger.Debug(debug, data);
}
public static void LogWarning(string warning, object[] data = null, Exception e = null)
{
logger.Warning(e, warning, data);
}
public static void LogError(Exception e, string error, object[] data = null)
{
logger.Error(e, error, data);
}
}
I want to write the logs produced by Serilog to Azure Application Insights inside the Mat2.Common project. Based on the very little I know about Azure Application Insights, it is installed/configured inside the website and API projects separately.
Is it possible to centralize the Azure Application Insights functionality just as the logging related functionality is centralized by putting it in the shared project?
The thing is that Azure Application Insights is a subscription-based product that is configured in an ASP.NET project. We pay for API and Website projects separately. While I am thinking of moving it to the shared C# project and then use it in two ASP.NET projects from the shared project.
I don't want to do this to reduce the cost but just to centralize the implementation. Does Microsoft allow something like this?
Since you are using Serilog for logging, you can remove the Application Insight from your API application and Website. When we use Application Insight in our project, it creates files and add code to some of our files.
To remove Application Insight, you'll need to first remove the NuGet packages and references from your application. We can uninstall NuGet packages by following any of the two following approaches:
Unistall using NuGet
To uninstall Application Insight, in the top menu select Tools > NuGet Package Manager > Package Manager Console.
Then enter the command :
Uninstall-Package Microsoft.ApplicationInsights.Web
-RemoveDependencies
Remove using Visual Studio NuGet UI
For step by step approach for this process and the above mentioned process check the following MS Document.
How to remove Application Insights.
The above mentioned approach will help you in removing the Application Insight, also could you please elaborate your question for more better understanding.

API versioning in .NET application

I need some clarification on API versioning in .Net Core framework.
My client want the version to be handled in Router level. Like
[Route("1/[controller]")]
public class SampleController : Controller
{
[HttpGet("version")]
public IActionResult GetVersion()
{
return Ok({"Message": "API Version 1"});
}
}
I access this using, https://www.somedomain.com/api/1/sample/version
In IIS, I will create an application called 'api' (The path 'api' in my URL will be taken care here) under default web site and host my code here.
In order to do API versioning, what is the better way that I can follow here.
Can I do this?
[ApiVersion("1")]
[Route("{version:apiVersion}/[controller]")]
public class SampleController : Controller
{
[HttpGet("version")]
public IActionResult GetVersion()
{
return Ok({"Message": "API Version 1"});
}
[HttpGet("version"), MapToApiVersion("2" )]
public IActionResult GetVersion()
{
return Ok({"Message": "API Version 2"});
}
}
Is it possible to create an application under an application in IIS. Like,
Default Web Site - > api -> 1 -> Code without API version mentioned
Default Web Site - > api -> 2 -> Updated Code without API version mentioned
Or can I create the versions as application in IIS and deploy the code under each applciation version. Like,
Default Web Site - > 1 -> Code without API version mentioned
Default Web Site - > 2 -> Updated Code without API version mentioned
This will end up in changing my API URL, which i don't prefer. I still want to go with the same URI.
I access this using, https://www.somedomain.com/api/1/sample/version
Please advise the best approach that I can follow here.
Here is a popular repository that provides a set of libraries for adding API versioning to ASP.NET Web API, OData with ASP.NET Web API, and ASP.NET Core applications.
For ASP.NET Core applications, you can install this repository's ASP.NET Core API Versioning by running the following command in the Package Manager Console:
Install-Package Microsoft.AspNetCore.Mvc.Versioning
Perhaps the Map extension method of ApplicationBuilder suits your needs :
app.Map( "/1", myVersion1MappingFunction)
in the Configure method of Startup let myVersion1MappingFunction configure a separate middleware pipeline:
private static void myVersion1MappingFunction( IApplicationBuilder app)
{
// start your special middleware for version 1
app.UseMvc( routes =>
{
routes.MapRoute( ... );
}
}
On using Map extension the fragment ("/1") is removed from HttpRequest.Path
If I understand you correctly are wanting to use URL Path Segment Versioning for ASP.NET Core. With that said in your examples you will NOT have separate website deployed. You have one website deployed and you do NOT create multiple applications for versioning under your default website.
With URL path segment versioning you have one web application and that application manages all routes using the ApiVersion convention. You will need to maintain the code in such a way that it can deliver old functionality with new functionality and manage all dependencies.
I would recommend reading what Microsoft has to say about this here and doing a simple proof of concept that makes sense for your implementation.
I hope this helps clear up your confusion about deploying the application multiple times for versioning.
In your case the best method would be to employ the versioning from the web server level so you can have different deployments and a folder per version without specifying a version in the application routing itself. (your option 2/3?)
However since IIS merely proxies requests to kestrel with .net core unlike asp.net, you'll have to setup the reverse proxy by URL/URL Re-write with ARR to different versions of the deployment.
So you could have:
/root/V1/
/root/V2/
etc... like you explain.
Each deployment would be running kestrel with different ports numbers and IIS would re-verse proxy to them by URL.
Here is an article on how to setup ARR with url-write. it's written with asp.net in mind, but it's the same principal:
Reverse Proxy with URL Rewrite v2 and Application Request Routing

Which method is called earlier SignalR Configuration or ASP.NET Application_Start?

I've SignalR 2.x and ASP.NET with ServiceStack framework. It makes to entry points, one per each pipeline:
Startup.Configuration(IAppBuilder app) -- for SignalR startup configuration
and
Global.Application_Start() in Global.asax.cs -- for initializing the standard ASP.NET pipeline.
I'd like to pass some object that has been created in Application_Start() into Configuration() (e.g. IOC instance). For this I'd like to be sure that Configuration() will be called after Application_Start().
I found this stackoverflow question. What bothering me is the slightly later definition. Does it mean the execution is overlapped? Is it promised that the code in Configuration() will be called after Application_Start() for sure?
Does anybody know how it is exactly working and what is this delay? Has anyone had an experience with coding these methods?
Thank you
Iv decided to confirm my previous (and incorrect) statement by experiment and indeed Application_Start() method is called before any Owin startup class which means before SignalR Configuration (assuming recommended SignalR configuration using Owin startup of course).
It is true that Owin (Microsoft.Owin.Host.SystemWeb to be precise - which is Owin host adapter for IIS) uses System.Web.PreApplicationStartMethodAttribute to hook into ASP.NET pipeline but only to register its own OwinHttpModule (and yes this registration happens before Application_Start()). But Owin startup classes are discovered and run during OwinHttpModule.Init() which happens after Application_Start(). Slightly later means exactly that - both methods are called during execution of HttpApplication.RegisterEventSubscriptionsWithIIS private method. No overlaping for sure...
Sidenote: Imho there is no reason to have startup\configuration in two different places in application and because OWIN is the next big thing in ASP.NET world (see vNext or SignalR) and offers more benefits than Application_Start() (such as switching startup configuration in web.config), I'm definitely planning to migrate all Application_Start() code to OWIN startup.
-> No reason to worry about what's happening 1st ;)
And this is also my suggestion to you!

What is the advantage of using web API over web method in ASP.NET

I am familiar with web method. Now I got a suggestion to use web API instead of web method. I had done a demo of ASP.NET web API it's more closer to a MVC architecture am using the classical asp.net web development. I don't like to mess up the controller (MVC concept) with classical development.
My web Method :
[WebMethod]
public static string GetName(int id)
{
return "testName";
}
My Web API controller:
public class MyController : ApiController
{
[HttpGet]
public string GetName(int id)
{
return "testName";
}
}
am really confused on this issue any one have a better idea on the same.
What is your suggestion on the same which is the better option?
How can i compare, if both having same piece of code?
The classic ASP.NET WebServices (what you call WebMethod) are a deprecated technology. There is no longer any active development. The ASP.NET Web API is a complete rewrite of the web stack from Microsoft in which you have far greater control for creating RESTful web services. This doesn't mean that you should choose between one or the other. There's also ServiceStack. If you are starting a new project you should stay away from classic webservices. If they are still present in the .NET framework it is for compatibility reasons with legacy code.
Complementing Darin's answer, if you want to test your method from ApiController, you can inject the object's dependencies using an DI container (http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver). The dependency injection is done automatically.
However, with webmethods, you can't use DI in that way because webmethods must be static. If you insist in using DI, you need to instantiate and call the container directly in each of the webmethods to get the dependencies to work on.

Winforms server side consumed by ASP.NET, WCF?

Where can I find a tutorial/sample of asp.net page consuming a WCF service that uses a winforms application server side?
Thanks
You are mentioning two separate and independent operations:
Consuming a WCF service from an ASP .Net application
Creating a WCF service that uses a win forms application
Which of them is the actual problem? Exposing functionality as a service separates the service consumer from the service provider. The service consumer (the ASP .Net application in your case) will never need to know the service provider (the WCF application) is implementing its functionality behind the scenes. All it needs to know is the public interface exposed by the service.
Update
If you are new to WCF, the video tutorials available here might be a good starting point. They present you the basic knowledge of exposing as well as consuming a service with WCF.
Now, related to "that uses a winforms application server side". I assume that what you are trying to do is expose in the service some of the functionality available in the win forms application. If that is the case all you have to do is reference the exe of the forms app (with Add reference in Visual Studio) inside the WCF app and call all the needed methods from there.
Even cleaner from an architectural perspective would be to separate the user interface (UI) and business logic (BL) of your win forms application in separate projects, which will result in separate binary files after compilation (an exe file corresponding to the UI and a dll for the BL). Then you will only need to reference the BL corresponding dll in the WCF service.
OK, This is what you need to do:
Create a Solution with a ASP.Net project in it. (Project A)
Go to File > Add > New Project and add a Windows Forms application. (Project B)
So, now you have two projects in your solution,
Add a reference from project B to project A.
Add a method that returns the main form of project B in Program.cs, here is an example:
public static class Program
{
public static MainForm mainForm;
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
mainForm = new MainForm();
Application.Run(mainForm);
}
public static MainForm RunForm()
{
Main();
return mainForm;
}
}
Define a new Thread in Global.asax > Application_Start to call the RunForm method and store the result in a static variable. example:
public static MainForm mainForm;
public void Application_Start()
{
new Thread(
() => { mainForm = Program.RunForm(); }
).Start();
}
(Don't forget to use using B;)
(If you don't run the form application in another thread, your website doesn't load.)
So, now you can access the main form using Global.mainForm
You can define some methods for showing MessageBox in MainForm class, and call them from the website! (The form doesn't need to be shown at all)

Resources