I keep reading about the importance of configuring ApplicationInsights to reduce unwanted traffic and other things.
How do I do that in an Asp.Net Core application? There doesn't seem to be an applicationinsights.config XML file anymore.
I can see a ConnectService.json file in the Application Insights folder, but there isn't much in it?
How do I configure AI for an Asp.Net Core application?
Anyone have links to docs? I can't seem to find any...
TIA
All of this is now in code, and mostly documented on the application insights asp.net core github wiki.
for example, see https://github.com/Microsoft/ApplicationInsights-aspnetcore/wiki/Dependency-Tracking-and-Performance-Counter-Collection where it has
Disabling Telemetry Module Services
In order to disable the services,
you need to manually remove the modules from the existing list of
services in the method ConfigureServices. Please note that telemetry
modules should be removed only after adding Application Insights to
the services.
// Removing dependency tracking telemetry module - to disable default dependency tracking
var dependencyTrackingService = services.FirstOrDefault<ServiceDescriptor>(t => t.ImplementationType == typeof(DependencyTrackingTelemetryModule));
if (dependencyTrackingService!= null)
{
services.Remove(dependencyTrackingService);
}
// Removing performance collector module - to disable default performance counter collection
var performanceCounterService = services.FirstOrDefault<ServiceDescriptor>(t => t.ImplementationType> == typeof(PerformanceCollectorModule));
if (performanceCounterService != null)
{
services.Remove(performanceCounterService);
}
Related
I'm developing a cross-platform (win/mac/linux) application and I'm looking to store my application state. What is the .NET Core recommended way of doing this?
I've dug through the documentation and the closest thing I found was this, which is aimed at Visual Studio/.NET Framework (and I'm on VS Code).
There are 3 ways,
ONLY For Localhost
Simply stash them in your appsettings.json or as environment
variables.
For Staging / Production,
Azure Key Vault
By utilising Azure Key Vault and the Microsoft.Extensions.Configuration.AzureKeyVault NuGet Package, you will be able to stash configurations for your projects in the best way possible in the actual environment.
You then simply inject it in,
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
var root = config.Build();
config.AddAzureKeyVault(
$”https://{root["KeyVault:Vault"]}.vault.azure.net/",
root[“KeyVault:ClientId”],
root[“KeyVault:ClientSecret”]);
})
.UseStartup<Startup>();
Although you still have to stash those 3 variables in, Azure has Azure AD to enforce access only to specified Applications. Thus, you need to register an application under the Azure AD in order for this to work. There are also restrictive features that will help you sandbox Azure Key Vault further.
Existing Vault Storages
Last but not least, the last way is to utilise existing vault storage options like HashiCorp. Libraries like https://github.com/rajanadar/VaultSharp will help you to implement it quickly and effectively. This is suitable for you if you primarily use a non-Azure provider for your servers.
As described here, you can use appsettings.json, which is generated and referenced within the new project template in dotnet new command
You can use the ConfigurationBuilder from the Microsoft.Extensions.Configuration nuget package
Although the docs are for ASP Core, you should be able to use them in your regular .Net Core app.
Create settings.json:
{
"mysetting": "value",
}
And use it:
var configuration = new ConfigurationBuilder()
.AddJsonFile("settings.json")
.Build();
// get the values from the settings.json
var mySetting = configuration["mysetting"];
Console.WriteLine(mySetting);
I'm trying to create a Web API project and a client-side web project, where the web project can access the API via ajax. Currently my project looks like this:
I saw this answer on here: Setting app a separate Web API project and ASP.NET app, which explains how the project url can be set to localhost:[port]/api.
But for ASP.NET 5 projects, the properties only have 3 tabs (as opposed to the several found in ASP.NET 4 projects):
What I'm wondering is:
Do I have to set this option somewhere else? (i.e project.json)
How would this work when I publish? Ideally I'd want [websiteURL]/api to serve up my API, whereas that link explicitly put localhost:8080.
Is having these as two projects a good idea? I could easily put API and web in the same project, but I like the separation of client-side and server-side logic.
Any help would be appreciated!
First Point:
Generally speaking in ASP.NET 5, the routing defaults are very good and should work out of the box without much in the way of configuration. You can use configuration and/or attribute based routing in your application (with a detailed overview of both here), although my personal preference is for the attributed approach. Provided you have the following line in your Startup.cs file (which you should have in a new project):
app.UseMvc();
you should be able to route requests to your api controllers in the fashion required (i.e. "/api/...") simply by using [Route] attributes as below (example taken from a standard generated ASP.NET 5 Web API application)
[Route("api/[controller]")]
public class ValuesController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
The above example will route any GET request made to "/api/values".
While this approach can be used to handle requests made to your api, in order to deliver the files needed for your front end javascript application/single page app, you will need to enable static file serving. If you add the following to the Configure method in your Startup.cs class:
app.UseStaticFiles();
this will allow your application to serve those static files - by default, these are served from the ‘wwwroot’ folder, although this can be changed in the project.json file if required. The files needed for your front end app should then be added to this folder. A tutorial on serving static files can be found here.
Second Point:
In my experience this will not be an issue when you publish your website - provided your server is set up correctly, you will not need to include the port when making a request - navigating to [yourwebsitename]/api/... will suffice.
Third point:
In my opinion this entirely depends on how large the project is likely to grow, although preference and opinion will vary from developer to developer. Generally speaking, if the project will remain small in scope then keeping both in a single project is perfectly ok, as unnecessary complexity is reduced. However it is also very useful as you have pointed out, to maintain a separation of concerns between projects. So aside from the organisational advantage of your approach, the respective dependencies of the two projects are/will be kept separate also.
I'm attempting to set up a Api App (Azure) with Swagger + Swashbuckle as demonstrated by Scott Hanselman at the //Build conference here: http://channel9.msdn.com/Events/Build/2015/2-628.
I have installed (using NuGet) the packages Swagger.Api and Swashbuckle.Core. It hasn't added any controller or settings that I would expect in order to have a swagger page. When I navigate to {baseUrl}\swagger, I get a 404 error.
I would think that since it has a UI it would require a Web App in addition to the Api App, but I've rewatched the demo and Scott clearly says you can add Swagger + Swashbuckle to any Api App. In a 2nd app though I'd think there may be issues with Api discovery. Has anyone set this up yet successfully?
Time rolls on and now Swashbuckle works for vNext (beta8 for me, probably other versions too) - thank you to the team and contributors!
In project.json add the package:
"Swashbuckle": "6.0.0-*",
In startup.cs in ConfigureServices():
services.AddSwaggerGen();
services.ConfigureSwaggerDocument(options =>
{
options.SingleApiVersion(new Info
{
Version = "v1",
Title = "My Super API",
Description = "A Super API using Swagger and Swashbuckle",
TermsOfService = ""
});
});
services.ConfigureSwaggerSchema(options =>{
options.DescribeAllEnumsAsStrings = true;
});
In startup.cs in Configure():
app.UseSwaggerGen();
app.UseSwaggerUi();
Now you can access your API doco - http://domain:port/swagger/ui/index.html
Access your Swagger definition - http://domain:port/swagger/v1/swagger.json
Then assuming you have at least one internet facing dev/uat/staging/prod environment, grab the definition URL then do File-> Import URI at http://editor.swagger.io/ - now you have code-gen for about 20 clients too :)
You can also setup your own code-gen server if you are so inclined too (https://github.com/swagger-api/swagger-codegen), however I leveraged the existing online generator. The online editor also has full model and relationship definitions too at least in my case where I fully defined my model using EF7 (I know, ick... but it's much better than <= EF6 and ServiceStack doesn't support CoreCLR, yet). Depending on the size of your project this could save you a few hours to a few weeks of work documenting, plus it is dynamically updating itself as you code more. And you can use it to test your endpoints too, but I still prefer PostMan.
Full sample project at https://github.com/mrsheepuk/ASPNETSelfCreatedTokenAuthExample/tree/beta8
Big ups to MrSheepUK
HTH
This answer is now outdated. See the other answer.
There is a nice blogpost describing the problem you have: https://alexanderzeitler.com/articles/Deploying-a-ASP-NET-MVC-6-API-as-Azure-API-App-in-Azure-App-Services/
This describes how you can add the Ahoy! package to an ASP.NET v6 Web Api project and adding this as an API app to Azure.
Here is another source: http://devmeetsbi.ghost.io/help-and-test-page-for-asp-net-web-api-asp-net-5-and-mvc-6/
You did all the right steps, but unfortunately for ASP.NET 5, Swashbuckle doesn't work yet.
You can get Ahoy! which is the next version of Swashbuckle that has ASP.NET v6 support here. That should make everything work.
I have a Windows Azure web role that contains a web site using ASP.NET MVC. When an HTTP request arrives and a page is first loaded the view (.aspx or .cshtml) is compiled and that takes some time and so the first time a page is served it takes notable longer than later serving the same page.
I've enabled <MvcBuildViews> (described in this answer) to enforce compile-time validation of views, but that doesn't seem to have any effect on their compilation when the site is deployed and running.
Azure web roles have so-called startup tasks and also a special OnStart() method where I can place whatever warmup code, so once I know what to do adding that into the role is not a problem.
Is there a way to force compilation of all views?
Take a look at Precompiled Razor Views by David Ebbo
Why would you want to do that?
One reason to do this is to avoid any runtime hit when your site
starts, since there is nothing left to compile at runtime. This can be
significant in sites with many views.
Also, you no longer need to deploy the cshtml files at all, resulting
in a smaller deployment file set.
Another cool benefit is that it gives you the ability to unit test
your views, which has always been something very difficult with the
standard runtime compilation model. I’ll cover that in more details in
a future post.
Turns out there's ASP.NET Precompilation that can be performed using ClientBuildManager.PrecompileApplication and mimics the on-demand compilation behavior, but just compiles every page. Tried it - the first load looks notably faster.
The non-trivial part is what to pass as ClientBuildManager constructor parameters. The solution is to enumerate all .Applications of the Site object and for each item in .Applications enumerate all .VirtualDirectories and use Path and VirtualPath from each item as parameters to ClientBuildManager constructor.
Is this an initial-load issue or a steady-state issue? One issue seen is that of app pool recycling, which defaults to 20 minute timeout. If you disable timeout (or set it to something large), is that a valid workaround?
Here's another SO answer discussing AppPool timeout and how to disable it. Basically:
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00
Add this to OnStart:
using (var serverManager = new ServerManager())
{
string siteName = RoleEnvironment.CurrentRoleInstance.Id + "_" + "Web";
var siteId = serverManager.Sites[siteName].Id;
var appVirtualDir = $"/LM/W3SVC/{siteId}/ROOT"; // Do not end this with a trailing /
var clientBuildManager = new ClientBuildManager(appVirtualDir, null, null,
new ClientBuildManagerParameter
{
PrecompilationFlags = PrecompilationFlags.Default,
});
clientBuildManager.PrecompileApplication();
}
If you use the Publish functionnality of Visual Studio, there is a much simpler option :
On the Publish dialog > Settings pane, expand File Publish Options and check Precompile during publishing then click configure. On the Advanced Precompile Settings dialog box, uncheck Allow precompiled site to be updatable.
source: https://msdn.microsoft.com/en-us/library/hh475319.aspx
I want to write a few web tests (over WatiN/Selenium + CassiniDev web server) for my asp.net web application.
Problem I encountered is that I dont know what to do in such situations:
there is a page where user can click the button to call some third-party service. In my web test i want to create mock of this service, which will always return static value (some value in these test case and other value in other test case).
How can i do that?
Currently i use IoC/DI container Microsoft Unity. And my pages gets his dependencies in a manner described in http://msdn.microsoft.com/en-us/library/ff664622%28v=pandp.50%29.aspx.
The only solution that comes to my head is: place all dependencies in web.config for each test case and copy necessary web.config on SetUp of test. This solution completly painful!
Any ideas?
I use WatiN and Cassini-dev in my integration tests as well and have had to deal with similar issues. In my setup fixture I deploy my Asp.Net web application to a temporary folder in my test folder which allows me to play around with the configuration before starting up cassini-dev. I use Windsor for my CI which allows me to change injected components at the configuration level. You may also be able to acheive this with Unity.
If the service you are referring to is a web service you just mock out a web service using the interface you have been coding to.
Here are the steps that I take when running my integration tests:
Create a temp web directory
Publish the Asp.Net web application to the temp directory (I use MSBuild to do this)
Deploy temp database (Using MSbuild and database projects but could be done a number of ways)
Deploy temp membership database (see my blog post on how to do this in code)
Update the web.config of the deployed Asp.Net web application to point to the temp databases and change any other settings relevant for testing.
Start up the website using Cassini-Dev. I also hit the site with a http request so that I can verify the site is up before running any tests.
Run the tests.
After running the tests you should clean up.
Stop cassini-dev
Delete the temp hosting folder
Delete the temp databases. I use Sql server SMO objects that allow me to query the Sql Server which I use to delete up any old databases that have been left lying around after any previously failed test runs.
How to deploy a website using MSbuild in code
var properties = new Dictionary<string, string>
{
{"Configuration", isDebug ? "Debug" : "Release"},
{"WebProjectOutputDir", tempHostingDirectory.FullName},
{"DeployToDatabase", "true"},
{"OutDir", Path.Combine(tempHostingDirectory.FullName, "bin\\")}
};
using (var engine = new ProjectCollection(properties))
{
engine
.LoadProject(<web project path>, "4.0")
.Build(new[] {"Build", "ResolveReferences", "_CopyWebApplication"});
}
Unity configuration section usage: http://www.pnpguidance.net/Post/UnityContainerUnityConfigurationSectionAppConfigWebConfig.aspx
Generating asp.net membership database in code: http://bronumski.blogspot.com/2011/06/generating-creating-aspnet-application.html
Msbuild ProjectCollection on MSDN: http://msdn.microsoft.com/en-us/library/microsoft.build.evaluation.projectcollection.aspx
It sounds like you are trying to mock a web service.
Web services usually inherit from MarshalByRefObject, this means you can create a mock by inheriting from RealProxy to create a transparent proxy that pretends to be the webservice:
class Mock : RealProxy
{
public Mock()
: base(typeof(IStuff)) { }
public IStuff GetStuff()
{
return (IStuff)GetTransparentProxy();
}
public override IMessage Invoke(IMessage msg)
{
IMethodCallMessage message = (IMethodCallMessage)msg;
// the message object provides the MethodInfo that was called
// as well as the arguments.
// <Insert logic here>
return new ReturnMessage(new NotImplementedException("comming soon to a test near you ..."), message);
}
}
I belieave NMock2 uses RealProxy for it's mocks, so you should be able to use it to mock the web service instead.