问题
Is there an easy way to add a subdirectory in ASP.Net v4 Web API that would contain all of my client content? I have read a lot of articles today on virtual paths and routing, but nothing that quite describes this case.
For example, I want to store my images under wwwroot so when the the app receives this request:
http://myapp/img/logo.png
It fetches wwwroot\img\logo.png to handle the request. Obviously, I don't want to have to map out every file or folder individually.
There will be a Web API restful web service that will be handled by the regular routing functionality in WebApiConfig.cs.
(Note: I ask this because I plan to migrate our app to ASP.Net v5 when it is GA, and this would make moving the client-side code trivial)
回答1:
You can use the Microsoft.Owin.FileSystem and Microsoft.Owin.StaticFiles NuGet Packages to achive what you want.
First add the two NuGet Packages.
Then add this Code to your Startup class:
public void Configuration(IAppBuilder app)
{
// here your other startup code like app.UseWebApi(config); etc.
ConfigureStaticFiles(app);
}
private void ConfigureStaticFiles(IAppBuilder app)
{
string root = AppDomain.CurrentDomain.BaseDirectory;
string wwwroot = Path.Combine(root, "wwwroot");
var fileServerOptions = new FileServerOptions()
{
EnableDefaultFiles = true,
EnableDirectoryBrowsing = false,
RequestPath = new PathString(string.Empty),
FileSystem = new PhysicalFileSystem(wwwroot)
};
fileServerOptions.StaticFileOptions.ServeUnknownFileTypes = true;
app.UseFileServer(fileServerOptions);
}
Also you have to make sure the handler is registered in your Web.config file. It should look like this:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthentication" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="Owin" verb="" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb"/>
</handlers>
</system.webServer>
Then every file in your "wwwroot" Folder will be automatically accessible.
For example your wwwroot/img/logo.png file will be accessible via http://yourdomain.com/img/logo.png, just like you want it :)
If you generate the content of the wwwroot folder with npm/gulp/grunt in a build event, then maybe you also have to edit your csproj file and add this ItemGroup:
<ItemGroup>
<Content Include="wwwroot\**\*" />
</ItemGroup>
回答2:
Add img folder to the root directory of your application. Also you have to to include images in the project or application
回答3:
For handling file routing I would:
- Create HttpHandler as workaround for Image handling/or some other static files.
- Bundle config for configuring
js
andcss
file path.
- Create HttpHandler for handling request to specific file extensions. And modify the file real path using provided file relative path from the URL.
HttpHandler for .jpg
files:
public class ServiceSettings
{
public static string RootStaticFolder = "\\wwwroot";
}
public class ImageHandler : IHttpHandler
{
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
var fileSystemPath = context.Server.MapPath(Path.Combine("~") + ServiceSettings.RootStaticFolder);
var file = Path.Combine(Path.GetDirectoryName(context.Request.FilePath), Path.GetFileName(context.Request.FilePath));
var filePath = string.Concat(fileSystemPath, file);
if(!File.Exists(filePath))
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
context.Response.Status = "404 Not Found";
}
context.Response.WriteFile(filePath);
}
}
For making it work you must disable MVC routing for this king of files.RouteConfig.cs
:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Disable routing for */*.jpg files
routes.IgnoreRoute("{*alljpg}", new { alljpg = @".*\.jpg(/.*)?" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Then you have to add registration for your HttpHandler to web.config
:
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="FormsAuthentication" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="jpgs" verb="*" path="*.jpg" type="WebApplication1.ImageHandler" preCondition="managedHandler"/>
</handlers>
</system.webServer>
Also pay attention to runAllManagedModulesForAllRequests="false"
setting in modules
tag.
Bundle configuration for css/js files
public static void RegisterBundles(BundleCollection bundles) { bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/wwwroot/Scripts/jquery-{version}.js")); // Use the development version of Modernizr to develop with and learn from. Then, when you're // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( "~/wwwroot/Scripts/modernizr-*")); bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/wwwroot/Scripts/bootstrap.js", "~/wwwroot/Scripts/respond.js")); bundles.Add(new StyleBundle("~/Content/css").Include( "~/wwwroot/Content/bootstrap.css", "~/wwwroot/Content/site.css")); }
With this approach it would be very easy during migration to asp.net 5. You will only need to remove HttpHandler and bundle configurations.
来源:https://stackoverflow.com/questions/33470123/map-to-wwwroot-in-asp-net-4