我一直在使用Web API处理ASP.NET MVC中的 AngularJS 项目。除非您尝试直接转到角度路由URL或刷新页面,否则它的效果很好。我认为这可以用 MVC的路由引擎来处理,而不是用服务器配置进行修改。
当前的WebAPIConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"^[0-9]+$" }
);
config.Routes.MapHttpRoute(
name: "ApiWithActionAndName",
routeTemplate: "api/{controller}/{action}/{name}",
defaults: null,
constraints: new { name = @"^[a-z]+$" }
);
config.Routes.MapHttpRoute(
name: "ApiWithAction",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "Get" }
);
}
}
当前的RouteConfig:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute(""); //Allow index.html to load
routes.IgnoreRoute("partials/*");
routes.IgnoreRoute("assets/*");
}
}
当前的Global.asax.cs:
public class WebApiApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.None,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
};
}
}
目标:
/ api / *继续转到WebAPI,/ partials / 和/ assets / 都转到文件系统,绝对其他任何东西都被路由到/index.html,这是我的Angular单页面应用。
- 编辑 -
我似乎已经开始工作了。将此添加到 BOTTOM OF RouteConfig.cs:
routes.MapPageRoute("Default", "{*anything}", "~/index.html");
这次更改为root web.config:
<system.web>
...
<compilation debug="true" targetFramework="4.5.1">
<buildProviders>
...
<add extension=".html" type="System.Web.Compilation.PageBuildProvider" /> <!-- Allows for routing everything to ~/index.html -->
...
</buildProviders>
</compilation>
...
</system.web>
然而,它闻起来像一个黑客。有没有更好的方法呢?
答案 0 :(得分:28)
使用通配符段:
routes.MapRoute(
name: "Default",
url: "{*anything}",
defaults: new { controller = "Home", action = "Index" }
);
答案 1 :(得分:12)
建议更多原生方法
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1"/>
<error statusCode="404" prefixLanguageFilePath="" path="/index.cshtml" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>
答案 2 :(得分:5)
就我而言,这些方法都没有奏效。我陷入了2个错误信息地狱。 此类网页未投放 或某种404.
url rewrite working:
<system.webServer>
<rewrite>
<rules>
<rule name="AngularJS" stopProcessing="true">
<match url="[a-zA-Z]*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
...
注意我在[a-zA-Z]上匹配,因为我不想重写任何.js .map等网址。
这在VS的hte框中工作,但在IIS中你可能需要安装一个url-rewrite模块https://www.iis.net/downloads/microsoft/url-rewrite
答案 3 :(得分:3)
我有一个与前几个答案类似的方法,但缺点是如果有人正在错误地进行API调用,他们最终会返回索引页面而不是更有用的东西。
所以我已经更新了我的内容,以便它会返回我的索引页面以查找不以/ api开头的任何请求:
//Web Api
GlobalConfiguration.Configure(config =>
{
config.MapHttpAttributeRoutes();
});
//MVC
RouteTable.Routes.Ignore("api/{*anything}");
RouteTable.Routes.MapPageRoute("AnythingNonApi", "{*url}", "~/wwwroot/index.html");
答案 4 :(得分:0)
好吧,我刚刚删除RouteConfig.RegisterRoutes(RouteTable.Routes);
中的Global.asax.cs
来电,现在无论我输入什么网址,如果资源存在,它都会被提供。甚至API帮助页面仍然可以使用。
答案 5 :(得分:0)
几天前,我一直在使用OWIN Self-Host和React Router,并引起了类似的问题。这是我的解决方法。
我的解决方法很简单;检查它是否是系统中的文件;否则返回 index.html 。如果您需要其他一些静态文件,因为您并不总是希望返回index.html。
在您的Web API配置文件中:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "{*anything}",
defaults: new { controller = "Home", action = "Index" }
);
,然后创建一个 HomeController ,如下所示...
public class HomeController: ApiController
{
[HttpGet]
[ActionName("Index")]
public HttpResponseMessage Index()
{
var requestPath = Request.RequestUri.AbsolutePath;
var filepath = "/path/to/your/directory" + requestPath;
// if the requested file exists in the system
if (File.Exists(filepath))
{
var mime = MimeMapping.GetMimeMapping(filepath);
var response = new HttpResponseMessage();
response.Content = new ByteArrayContent(File.ReadAllBytes(filepath));
response.Content.Headers.ContentType = new MediaTypeHeaderValue(mime);
return response;
}
else
{
var path = "/path/to/your/directory/index.html";
var response = new HttpResponseMessage();
response.Content = new StringContent(File.ReadAllText(path));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
return response;
}
}
}