Can no longer access the list of API descriptors after installing Glimpse - asp.net-mvc-4

We would like to use Glimpse in our ASP.net MVC project but are running into a problem when accessing the list of Web API descriptors.
We have installed Glimpse.Mvc4 1.2.2 using the Nuget Package Manager.
The following snippet gets all API descriptors and it works fine before we install Glimpse. After installing we do only get an empty list.
IEnumerable<ApiDescription> apiDescriptors = System.Web.Http.GlobalConfiguration
.Configuration
.Services
.GetApiExplorer()
.ApiDescriptions
Does anyone know why this call does not work when Glimpse is installed?

The problem is that the Glimpse ASP.NET module wraps all routes in its own objects. So API Explorer ignores them (thinks that they are not Web API routes).
To work around this issue, you must initialize a fresh copy of System.Web.Http.HttpConfiguration instead of using GlobalConfiguration.Configuration.
// need to create a custom configuration instance because the default one can be
// processed by Glimpse and be thus full of wrapped routesthat the ApiExplorer
// does not recognize.
var config = new System.Web.Http.HttpConfiguration();
WebApiConfig.Register(config);
// these line is useful if you use WebAPI Help page package
HelpPageConfig.Register(config);
Controllers.HelpController.Configuration = config;
// otherwise just get the `IApiExplorer` interface from the fresh configuration:
var apis = config.Services.GetApiExplorer().ApiDescriptions;

Related

How to republish an ASP.NET Core 5 web application in IIS. Changes not taking effect

I've published an ASP.NET Core 5 Web API to IIS (using VS 2019 webdeploy), and it is running fine. Now I've made some minor changes and republished.
The changes take affect on my local machine using IIS Express, but I do not see them when I publish to my IIS server. I can see that the exe and dlls are updated, but the webapi behaviour does change.
Something as simple as setting the swaggerdoc title doesn't take affect.
Is there something else I need to do to refresh the app? I've tried recycling the app pool and doing an iisreset, but no luck. I've read that IIS is merely acting as a reverse proxy to Kestrel which is actually hosting the api. If so how do I recycle that?
As a test, I delete all the files in my web api directory. I browse to the web api and get the following error:
HTTP Error 500.31 - Failed to load ASP.NET Core runtime Common
solutions to this issue: The specified version of
Microsoft.NetCore.App or Microsoft.AspNetCore.App was not found.
Troubleshooting steps:
Check the system event log for error messages
Enable logging the application process' stdout messages Attach a
debugger to the application process and inspect For more information
visit: https://go.microsoft.com/fwlink/?LinkID=2028526
I then re-publish the web api and browse to it, but it still has the old behavior. I'm really confused, because I know the published dll for my service is correct.
If I use ILSpy I can see the following code:
public void ConfigureServices(IServiceCollection services)
{
IConfigurationSection appSettingsSection = Configuration.GetSection("ApplicationSettings");
ApplicationSettings appSettings = appSettingsSection.Get<ApplicationSettings>();
services.AddSingleton(appSettingsSection.Get<ApplicationSettings>());
services.AddControllers()
.AddXmlSerializerFormatters()
.AddJsonOptions(delegate(JsonOptions o)
{
o.JsonSerializerOptions.PropertyNamingPolicy = null;
o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
services.AddSwaggerGen(delegate(SwaggerGenOptions c)
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "My Demo Service (" + appSettings.Environment + ")",
Version = "v1"
});
});
}
When I browse to the swagger page of my API on my local dev box the title matches code, and the property naming is what I want. When I browse to it on the server, the title of the swagger page is the old value, and the property naming policy is camel case, so I'm pretty sure I'm publishing the new version of my web api, but it's not being executed when I make http requests to the api. Something must be cached somewhere.

ASP NET Core Web API returning a link to an image failing

I have a working ASP.NET Web API. I am currently converting it to ASP.NET Core 3.1.
In one of the API calls, I check if an image is present in a folder. If it is not, I create it (in code) and then send a link to it (amongst other things) back to the caller. The check if exists and creation of the image works fine in ASP.NET Core, but when I send back the link to the image, the client does not find it and hence it appears as a broken link on their web page.
See this diagram for the structure and for example the EnabledTRImage.png file.
The Url I am returning is:
http://localhost:59682/TR/128/EnabledTRImage.png
I have also tried returning:
http://localhost:59682/wwwroot/TR/128/EnabledTRImage.png
But this fails too.
One thing I have noticed is that in ASP.NET Core, creating the image in code makes it part of the Project, whereas in ASP.NET it does not. I was wondering if that had anything to do with the issue.
Unfortunately, these images are central to the Web API. So I am stuck.
Any ideas? Thanks
I just fixed it myself. I had not specified:
app.UseStaticFiles();
In the Startup/Configure method. That line is not there in the WebApi template (as expected I guess)
In the Startup/Configure method.
Instead of app.UseStaticFiles();
Specify your folder path in StaticFileOptions()
app.UseStaticFiles(new StaticFileOptions(){
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), #"ProductImagesFiles")),
RequestPath = new PathString("/ProductImagesFiles")
});
'

Web Api documentation with swashbuckle

We are currently trying to start writing WebApi services for our products switching from traditional WCF SOAP based services. The challenge we have got is how to provide the api documentation. I came across the SwaggerUi/swash buckle.
One limitation we have is we do not want to host the WebApi services in IIS but in a Windows Service. I am new to Web Api so I might be doing things the wrong way.
So for testing, I am hosting the web api in a console application. I can use the HttpClient to invoke the Get method on the Web Api but I can't access the same if I type the url in a web browser (is this normal for self hosted web api?).
So I installed the Swashbuckle.core nuget package and included the following code in the Startup class (Owin selfhosted).
var config = new HttpConfiguration();
config
.EnableSwagger(c =>
{
c.IncludeXmlComments(GetXmlCommentsPath());
c.SingleApiVersion("v1", "WebApi");
c.ResolveConflictingActions(x => x.First());
})
.EnableSwaggerUi();
private static string GetXmlCommentsPath()
{
var path = $#"{AppDomain.CurrentDomain.BaseDirectory}\WebApiHost.XML";
return path;
}
When I browse to the following location
http://localhost:5000/swagger/ui/index
I get "page cannot be displayed" in IE. Similar for chrome.
Is there anything special that needs to be done when hosting a WebApi in a console/windows service application to get the documentation automatically?
(I have enabled Xml documentation for the project)
I have now attached a test project. Please follow the link below:
Test project
Regards,
Nas
Your problem is not with Swashbuckle, which is configured correctly. Instead it is with the fact that your OWin web app has closed by the time the browser navigates to the swagger URI. Your using statement means that the web app is shut down at the end of it - well before Chrome has opened and navigated to the swagger path. You need to ensure the web app is still running - then your path will be valid (although in your source code you have different ports 9000 and 5000 in your url variables).

Creating ASP.NET MVC4 project to connect to SiteCore Master for Admin Access

I have a SiteCore 6.5 already installed, and I just want to create a simple ASP.NET MVC4 application that will connect to the Sitecore\Admin, and allow me to call Context.GetItem("/sitecore/content/home") function call. Is there an easy of doing this? What do I have to change in the web.config to make this happen? This is used as a simple Admin toolbox app, so all of the username and password are hardcoded for the connection, and I am just using the SecurityDisabler() and UserSwithcher() to run the function under Admin.
Take a look at the Sitecore Item Web API module, it's available on the SDN. The API gives access to content through items paths, IDs, and Sitecore queries.
The Item Web API was the subject of a presentation at this month's London User Group meeting. You can find a recording of the presentation on YouTube and the demo code is available on GitHub.
If you want to understand what is required to use the standard Sitecore API's to access content items outside of the website context Mike Edwards has a great post on How to configure Sitecore 6.5 to work in NUnit. This post explains what configuration will be required in the caller to access Sitecore without a context and it will then be possible to execute code like the following:
using NUnit.Framework;
using Sitecore.Data;
using Sitecore.Data.Items;
[TestFixture]
public class when_connecting_to_sitecore_master_database
{
[Test]
public void it_can_retrieve_the_root_item()
{
Database db = global::Sitecore.Configuration.Factory.GetDatabase("master");
Item item = db.GetItem("/sitecore");
Assert.IsNotNull(item);
Assert.AreEqual("sitecore", item.Name.ToLower());
}
}
I was able to connect a MVC 4 app to the Sitecore 6.5 installation for some admin implementations. I just copied the entire folder for App_Config and Web.Config file to the MVC app, and the start to migrate the MVC4 web.config into the copied web.config from the installations. I then started to take out pieces one at a time, most of the part that you should take out will show up in the as error when you run the application, but the main part that we giving me an error was the httpredirection to the sitecore installation, and that was the httphandlers tag and httpModules tag, and my MVC app showed right now, and I was able to connect to the Sitecore configuration and factory.

ASP.NET WebAPI fails from MVC4 controller

I'm new to ASP.NET Web API and I'm struggling with a very strange problem.
I have some code which calls a RESTful service and it executes fine from a console project, but I can't get it to run from an MVC4 project running under .NET 4.0
The code to call the service is very simple:
internal string Test()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://testserver");
var task = client.GetAsync("/someUri")
var response = task.Result;
response.EnsureSuccessStatusCode();
return response.Content.ReadAsStringAsync().Result;
}
}
As mentioned, called from a console project it works as expected and I get a response in milliseconds, however if I call the method from an action in my MVC4 controller after a few seconds I get a message stating that:
"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to repond".
Weirdly, when debugging the MVC4 version, the task status always shows as WaitingForActivation.
Running fiddler doesn't show any request being made from the MVC4 version, but again does for the Console version.
After a fairly serious bit of googling I can't find anyone else who seems to have had this problem, so I'm guessing that I've fundamentally misunderstood something, but at the moment I'm not sure what!
Updated 16:55 BST, 11/09/2012
To make things even weirder, I've just created a new MVC4 site and I can call the method without any problems! I'm now trying to compare the sites, however one was an existing site that was upgraded to MVC4 and the other is a new blank site, so spotting the relevant difference could be tricky.
Updated 16:44 BST, 14/09/2012
This is now looking like some infrastructure / networking issue.
I upgraded the project to VS2012 with .NET 4.5 so that I could use async/await to try the suggested implementations to avoid a deadlock. This didn't change anything so I went back to square 1.
I created a new solution with a new MVC4 project, a new services library and a unit test project to run the service library outside of MVC.
In the service library I created one method to call a public "what's my IP" service, and another to call a company service that's exposed publicly but only responds properly to company IP addresses.
For some background, I connect in to the company LAN via a VPN.
When disconnected from the VPN, in both unit tests and MVC, the IP service responds HTTP 200, the company service responds HTTP 404 as expected.
When connected to the VPN, unit tests both respond HTTP 200, MVC both timeout.
Next I ran MS Soap Tool locally and used that to proxy calls to the company services. All calls (whether from unit tests or MVC) show a request and response, but the unit test registers the response whilst the MVC controller does not.
My only other thought is that it could be something to do with the size of the reply? All the "successes" have very small replies other than the unit test calling the company service?
The Microsoft recommended way to upgrade an MVC3 to MVC4 site is to start with a completely new MVC4 site a migrate your views, controllers & code over. So I think that your upgrade steps may be part of your issue, since you were able to get it to work in the new MVC4 site you created. If you need to manually upgrade your existing site, I would follow the steps outlined in Upgrading ASP.NET MVC 3 Project to ASP.NET MVC 4