Web API 이외의 모든 것을 /index.html로 라우팅하는 방법
Angular를 작업하고 있는데JS 프로젝트, ASP 내부.Web API를 사용한NET MVC라우팅된 각 URL로 직접 이동하거나 페이지를 새로 고치려는 경우를 제외하고 매우 잘 작동합니다.서버 설정으로 장난치는 것이 아니라 MVC의 라우팅 엔진으로 처리할 수 있다고 생각했습니다.
현재 WebAP Config:
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/는 모두 파일시스템으로 이동합니다.다른 모든 것은 Angular 단일 페이지 앱인 /index.html로 라우팅됩니다.
--편집--
제대로 된 것 같아요.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>
하지만 냄새는 고약하다.더 좋은 방법은 없나요?
와일드카드 세그먼트 사용:
routes.MapRoute(
name: "Default",
url: "{*anything}",
defaults: new { controller = "Home", action = "Index" }
);
보다 네이티브한 접근법 제안
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1"/>
<error statusCode="404" prefixLanguageFilePath="" path="/index.cshtml" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>
제 경우엔 이 방법들 중 어떤 것도 효과가 없었습니다.2개의 에러 메세지 hell에 갇혔다.이런 종류의 페이지는 제공되지 않거나 404 같은 종류입니다.
url rewrite 동작:
<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 등의 URL을 다시 쓰고 싶지 않기 때문입니다.
이는 VS out-of-hte box에서는 동작하지만 IIS에서는 url-disl 모듈을 설치해야 할 수 있습니다.https://www.iis.net/downloads/microsoft/url-rewrite
상위 몇 개의 답변과 유사한 접근 방식을 사용했지만, 단점은 누군가가 API 호출을 잘못하면 더 유용한 것이 아닌 인덱스 페이지를 다시 얻을 수 있다는 것입니다.
그래서 /api로 시작하지 않은 요청에 대해 인덱스 페이지를 반환하도록 mine을 업데이트했습니다.
//Web Api
GlobalConfiguration.Configure(config =>
{
config.MapHttpAttributeRoutes();
});
//MVC
RouteTable.Routes.Ignore("api/{*anything}");
RouteTable.Routes.MapPageRoute("AnythingNonApi", "{*url}", "~/wwwroot/index.html");
며칠 전부터 OWIN Self-Host 및 React Router를 사용하고 있는데, 비슷한 문제가 발생했을 가능성이 있습니다.제 해결책은 이렇습니다.
회피책은 간단합니다.시스템에 파일이 있는지 확인하고, 그렇지 않으면 index.html을 반환합니다.다른 정적 파일이 요청되었을 때 index.html을 반환하고 싶지 않기 때문입니다.
웹 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;
}
}
}
음, 방금 제거했어RouteConfig.RegisterRoutes(RouteTable.Routes);을 불러들이다Global.asax.cs어떤 URL을 입력해도 리소스가 존재하면 서비스가 제공됩니다.API 도움말 페이지도 여전히 작동합니다.
언급URL : https://stackoverflow.com/questions/19643001/how-to-route-everything-other-than-web-api-to-index-html
'programing' 카테고리의 다른 글
| jQuery - .getjson VS .ajax json (0) | 2023.03.15 |
|---|---|
| ERROR 404.3 JSON 파일을 찾을 수 없습니다. (0) | 2023.03.15 |
| MongoDB 쿼리를 JSON으로 변환하려면 어떻게 해야 하나요? (0) | 2023.03.15 |
| 표현식에 대한 느린 각 일회성 바인딩 (0) | 2023.03.15 |
| 봄철 웹 소켓 인증 및 인가 (0) | 2023.03.10 |