Right now I'm developing an ASP.Net Web API and using Swashbuckle for its documentation.
I know that Swashbuckle use Swagger-UI internally, I know that we can modify the layout by injecting our css or javascript file, even change the layout of index.html.
I found a good themes for Swagger-UI https://github.com/jensoleg/swagger-ui and trying to implement it but can't make it works. Especially when I want to inject bootstrap.js. Is there anyway I can completely change Swashbuckle Swagger UI implementation so I can use the solution from that repo?
Sure you can - in two steps.
1) Include file Index.html as Embedded resource in your assembly. For example let's say your web api project is named "Contosco.Api" and Index.html will be located under "/Content/Index.html" in this project.
2) Override swagger UI main html page with your own
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration.EnableSwagger(c => {
// configure swagger
})
.EnableSwaggerUi(c => {
// beware - the Contosco.Api.Content.Index.html has to match your project paths :)
c.CustomAsset("index", thisAssembly, "Contosco.Api.Content.Index.html");
});
}
}
For .NET Core projects the solution differs a bit from the (correct) answer of #OndrejSvejdar:
After adding index.html as an embedded resource, you have to add the following line to app.UseSwaggerUI() in your Startup.cs...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
app.UseSwaggerUI(c =>
{
c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Your.Default.Namespace.Subfolder.Swagger_Custom_index.html");
});
//...
}
All details of the process can be found here: https://stackoverflow.com/a/51043251/430742
You just download .zip folder, extract and include to your project.
In SwaggerConfigre.cs you don't need configure any more.
Just put template into folder Swagger and when you access {domain}/swagger it will hit index.html. (Don't need change Build action to Embedded Resource, Content is fine)
I was able to use the latest swagger-ui by following the simple steps here ,https://swagger.io/docs/swagger-tools/#swagger-ui-documentation-29
Download the swagger-ui from GitHub
Extract and copy the dist (rename folder to swagger) folder and include it in the project
Modify index.html in the dist folder to point to your swagger doc path (which off course is generated by Swashbuckle)
Related
I'd like to bundle many static files from various dirs in a meteor appplication. I have a different folders structure than the standard prescribed. I have static files in various directories and I serve them using the webapp. This works in dev on my machine where I access them directly by a path from C:\.... But when the app is bundled those files will not make it to the bundle. Is there any way how to tell meteor that it should also bundle those directories?
I try to achieve an encapsulation of modules. So each module would have its own static files and each would be a pack of all source and static files needed to run within an app. The static files need to be inside app folders. I have a Modules dir where are modules like Users and Notes and each of the modules can have its own static files which would be accessed by url and later by node fs, but they are not imported by js. That's why they'll not get into the bundle.
The files are consumed by
const realpath = path.normalize(base + filepath);
const data = fs.readFileSync(realpath);
res.writeHead(200, { "Content-Type": mime.lookup(realpath) });
res.write(data);
res.end();
Where filepath is calculated by function from url.
I explicitly don't want to use public folder or any folder of standard meteor folder structure. I have defined custom folder structure with idea of encapsulation in mind. I'm aware of api.addAssets(filenames, architecture) but that's only for packages AFAIK. But that's something as I'd need I guess. I'd expect that there would be possibility to write some script that would run while bundling and would provide information for bundler which files to include.
Thanks.
Using meteor's /private directory would prevent any public access, and allow you to bundle your application code.
I have built an Angular-CLI .Net Core SPA with Visual Studio 2017 by using
dotnet new angular -o my-new-app
What I am struggling to find is how index.html which lies inside ClientApp/src folder is called by default when write e.g.
http://localhost:57782
startup.cs file has as follows:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace angular_cli
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//services.AddMvc();
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseSpaStaticFiles();
//app.UseMvc(routes =>
//{
// routes.MapRoute(
// name: "default",
// template: "{controller}/{action=Index}/{id?}");
//});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
}
}
On purpose, I have disabled MVC middleware and everything works fine. However, I have no idea by which mechanism and settings index.html is called... Any good explanations please?
So I had exactly the same question but for React App (I guess that for angular is very similar). I spent last 2 hours on investigation how things works under the hood and I'm still not quite sure If I'm right but thats what I found out:
Development
spa.UseReactDevelopmentServer(npmScript: "start");
This method runs npmScript called start - you may find it in package.json file in scripts section. This script starts WebPackDevServer which performs webpack pipeline in memory and then serves generated files also from memory (it allows reloading files in browser quickly and without rebuilding application which is great for development).
Webpack pipeline generate necessary js & css scripts, inject links to those files into index.html and then copy all necessary files into specified directory (or memory in this case ;))
It setup proxy to that server so ASP passes all request to that server and ultimately your files are just served from memory.
You may also run this server directly from console and instruct ASP to setup proxy to existing server without starting npm script. It may be achieved by using UseProxyToSpaDevelopmentServer method.
Production
In case of production build the server is not (and should not be) used. The build script should be called (by PublishRunWebpackstep which you can find in csproj file) which will run similar pipeline which will produce minified files and proper index.html into specified folder. Then those files will be served directly from HDD thanks to AddSpaStaticFiles configuration.
At least this is my current understanding of this process.
Maybe it is late for this question, but I met the same problem to figure out how index.html, which lies inside ClientApp/src folder, is called by http:// localhost:57788, and this is what I found.
According Microsoft's requirement for app.UseSpa method:
Handles all requests from this point in the middleware chain by
returning the default page for the Single Page Application (SPA). This
middleware should be placed late in the chain, so that other
middleware for serving static files, MVC actions, etc., takes
precedence.
That means all requests without registered, valid routes (http:// localhost:57788 does not have any controller, which is necessary according that project's route configuration) will reach and activate app.UseSpa middleware. The Framework to get path to the angular bootstrap Index.html file, first picking from spa.Options.SourcePath property (ClientApp) folder name , then looking for "baseUrl" in ClientApp /src/tsconfig.app.json file ("./"), which is the folder where index.html should reside. In case the framework found index.html file in ClientApp/src/ folder sending it to the client.
For verification you can try:
1. if you change src folder name to src_, you will get this error:
Error: ENOENT: no such file or directory, stat 'C:..... \ClientApp\src \tsconfig.app.json'
2. if you change index.htm file name to index__.html you will get this error:
Cannot GET /
3.Request with valid rout: http:// localhost:57788/SampleData/WeatherForecasts is returning json data.
If you request server directly, you should be served with index.html in 'ClientApp/dist' folder given here:
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
and you are calling that service here:
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
If you are in development environment which you are, it will use npm start command which is equal to ng serve in the SourcePath you defined above, to start angular server and proxy requests to angular server. Actually displayed index.html is just on memory and neither in dist folder nor in wwwroot.
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
It is provided by Static Files Middleware that is registered by
app.UseStaticFiles();
You may read about it here: Work with static files in ASP.NET Core
Github repo: https://github.com/aspnet/StaticFiles
What I am struggling to find is how index.html which lies inside
ClientApp/src folder is called by default when write e.g.
It doesn't use index.html. Instead, it calls Home controller's Index action method.
http://localhost:57782 is same as http://localhost:57782/Home/Index. It is basically an entry point for the entire application.
You can see it inside Startup.cs
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
After the application is published, index.html is added all css and js resources and copied to dist folder. The index.html file is loaded by default. Basically it depends on Default document setting in IIS (on Windows).
I hit the same issue as you and this was the first place I came for an answer.
The solution actually was:
app.UseDefaultFiles();
After that hitting http:domain/ served the index.html as expected.
Source
I'm working on a web service using spring-boot-starter-jersey and spring-boot-starter-tomcat (v. 1.5.2) and as such, I'd rather not add spring-boot-starter-web and further complicate my configuration. I want to stick the Swagger UI static files in a folder and serve them from there.
What I'm wondering is, can I serve static files using just spring-boot-starter-tomcat? I've found Spring documentation saying that I can server static content from a variety of sources on the classpath, but the examples I've found seem to require Spring MVC. I've tried disabling Jersey and putting static files in src/main/resources/static to test just Tomcat, but when I go to localhost/index.html, I get a 404 not found error.
As you might be able to tell from my path, I'm using Maven.
Since you can serve static files with just Tomcat, it seems like I should be able to serve static files with spring-boot-starter-tomcat. If this is the case, where do I put those files?
To put this another way, say I have started with the Spring-provided
spring-boot-sample-jersey project. I have a requirement that the Jersey web service answer calls to the root address (/). How would I add some static content (HTML, CSS, JS) to be served from subdirectory called /swagger?
So the default servlet (which serves static content) is by default registered. But it will use only search specific paths as the document root. I had to go digging through source code to finally find it. If you look in the AbstractEmbeddedServletContainerFactory, you'll see
private static final String[] COMMON_DOC_ROOTS = {
"src/main/webapp", "public", "static" };
If we don't explicitly set the document root, the above three are the paths that will be searched. In order, the first directory found that exists, will be used as the document root. I've verified that all of these work.
If you want to set a different directory, you can use a customizer bean
#Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
return new EmbeddedServletContainerCustomizer() {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setDocumentRoot(new File("src/main/resources/static"));
}
};
}
The one thing I haven't figured out is if we can serve files as classpath resources, instead of file system resources. If you look at the source code I linked to, it has some code that looks for the existence of a META-INF/resources. I thought that might work, but unfortunately it didn't for me. Maybe some guys of the Spring Boot team can enlighten us.
Can you suggest me some articles or code samples about plugin architecture in web api?
Currently I'm thinking about this scenario: to have 1, centralized api gateway, where every client sends request, and have different applications controllers in Plugins folder. If someone wants to add new service, writes it's own controllers and puts dll files in Plugin folder.
For locating controller classes at run time, you can write an assembly resolver, like this.
public class MyAssembliesResolver : DefaultAssembliesResolver
{
public override ICollection<Assembly> GetAssemblies()
{
List<Assembly> assemblies = new List<Assembly>(base.GetAssemblies());
// Add all plugin assemblies containing the controller classes
assemblies.Add(Assembly.LoadFrom(#"C:\Plugins\MyAssembly.dll"));
return assemblies;
}
}
Then, add this line to the Register method in WebApiConfig.
config.Services.Replace(typeof(IAssembliesResolver), new MyAssembliesResolver());
With this, the request will still need to be sent to the individual controller even though the controller classes can come from assemblies in the plugin folder. For example, if MyAssembly.dll in the plugins folder contains CarsController, the URI to hit this controller will be /api/cars.
I have an ASP.NET application, and I am trying to turn this into a hybrid ASP.NET / ASP.NET.MVC 4.0 application.
I tried to create a folder named "Controllers", and place a .cs file in there:
public class PlayerGroupController : Controller
{
public PlayerGroupController()
{
}
public string Index()
{
return "Hello World!";
}
public ActionResult LayoutTemplates()
{
return View();
}
}
Any attempt to access "PlayerGroup/LayoutTemplates" doesn't work (just get a "Not Found" error)
I then moved this file into App_Code, and it works fine. I'm glad I got something working, but I would rather follow the convention of controller classes being in the folder named Controllers.
Is there some magic setting I can set somewhere so that it starts recognizing Controllers as a code folder?
If the project is configured as a Web Site Project then all code files (*.cs) must be in ~/App_Code or in subfolders thereof. If the project is a Web Application Project, code files can go anywhere in the project and be compiled by VS into a DLL that ends up in the ~/bin directory, which then gets loaded by ASP.NET.
MVC is geared specifically towards the Web Application Project (WAP), so I recommend creating a new WAP and copying all the files into that, and then going from there.