Inn*_*ang 6 asp.net-mvc virtual-directory asp.net-web-api
由于各种工程需求,我需要在现有应用程序(名为FooApp)的同一Application域中开发一个新的ASP.NET Web API应用程序(名为BarApp).
我想将ASP.NET Web API应用程序(BarApp)配置为IIS 8.5上现有ASP.NET MVC应用程序(FooApp)下的虚拟目录.虽然许多帖子都谈到了如何配置虚拟目录,但它们都不起作用.
这是配置代码段
<site name="FooApp" id="3" serverAutoStart="true">
<application path="/" applicationPool="FooApp">
<virtualDirectory path="/" physicalPath="E:\FooApp" />
<virtualDirectory path="/Bar" physicalPath="E:\BarApp" />
</application>
<bindings>
<binding protocol="https" bindingInformation="*:34566:" sslFlags="0" />
</bindings>
</site>
Run Code Online (Sandbox Code Playgroud)
这是网站结构:
-FooApp
|
|--Bin
|--View
|--Bar (as a virtual directory)
|
|--Bin
|--View
Run Code Online (Sandbox Code Playgroud)
在Foo App中,我配置了路由:为Bar添加所有路径的ingore路由
--RouteConfig.cs
namespace FooApp
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*path}", new { path = @"Bar\/(.*)" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
Run Code Online (Sandbox Code Playgroud)
--WebApiConfig,保留自动生成的一个.
namespace FooApp
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在BarApp中,路由配置被修改为:
--RouteConfig.cs
namespace BarApp
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "Bar/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
--WebApiConfig
namespace BarApp
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "Bar/api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,上述配置不起作用,忽略路由似乎没有生效.
无法访问Bar的页面:https:
//mywebsite.test.com :4433/Bar / HTTP Error 403.14 - Forbidden Web服务器配置为不列出此目录的内容.
无法访问Bar的Web API:https: //mywebsite.test.com :4433/Bar/api/value HTTP错误404.0 - 未找到您要查找的资源已被删除,名称已更改或暂时不可用.
Web API库是2.2.1
我认为您的方法的问题是尝试在虚拟目录中托管Asp.Net应用程序.相反,您必须添加子应用程序:

然后修改根应用程序的web.config以避免配置冲突:

参考:禁用子应用程序中的继承以及validateIntegratedModeConfiguration和inheritInChildApplications冲突.
这样,您就可以在不修改任何c#代码的情况下访问您的子web api:

我没有使用配置文件来设置虚拟应用程序(仅通过IIS和发布),但是我认为您遇到的问题是了解如何在虚拟应用程序中映射路由URL。对于以下内容,假设您的FooApp的DNS设置为fooapp(http://fooapp/)。
如果在fooapp下有Bar虚拟应用程序,则Bar网站的根目录为http://fooapp/Bar。如果我们查看您的路由定义(MVC和WebApi):
// MVC Route
routes.MapRoute(
name: "Default",
url: "Bar/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// WebApi Route
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "Bar/api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)
您的两条路由都设置为侦听Bar正在运行的应用程序下的“目录”。如果您的WebApi应用程序是我们自己发布的(例如在localhost上发布),则为http://localhost/Bar。但是您实际上是在下面http://fooapp/Bar,它将基于该根路径http://fooapp/Bar/Bar(所以 http://fooapp/Bar/Bar/api/values等)捕获请求。
就忽略路由而言,如果中没有控制器处理路由,则应用程序将告诉IIS,它不知道如何处理请求,然后IIS将移至其他处理程序(静态文件处理程序,依此类推)/Bar。FooApp上)。让我们以您的请求为例(https://mywebsite.test.com:4433/Bar/)。由于它在虚拟应用程序下,它将询问该Bar应用程序是否可以处理/路由。由于您在Bar应用程序中的路由定义仅处理/Bar/{tokens},因此它将默认为静态文件处理程序(在这种情况下为目录浏览),并由于配置而返回403。
如果您使用第二个示例(https://mywebsite.test.com:4433/Bar/api/values),它将询问Bar应用程序是否可以处理它不能处理的/api/values内容(请记住,它可以处理/Bar/api/values,不能处理/api/values)。由于您的应用程序无法处理,因此它将返回到其他处理程序,并且没有人能够满足该请求并返回404。