Closed mmunchandersen closed 8 years ago
Please see https://github.com/turquoiseowl/i18n#exclude-urls-from-being-localized. Thank you.
Here is how you can exclude APIs from localization:
i18n.UrlLocalizer.OutgoingUrlFilters += delegate(string url, Uri currentRequestUrl) {
Uri uri;
if (Uri.TryCreate(url, UriKind.Absolute, out uri)
|| Uri.TryCreate(currentRequestUrl, url, out uri)) {
if (uri.LocalPath.IndexOf("/Api", StringComparison.OrdinalIgnoreCase) != -1) {
return false; }
if (uri.LocalPath.IndexOf("xdomain", StringComparison.OrdinalIgnoreCase) != -1) {
return false; }
}
return true;
};
update:
when I use:
i18n.UrlLocalizer.IncomingUrlFilters += delegate(Uri url)
{
if (url.LocalPath.Contains("/api"))
return false;
return true;
};
instead of:
i18n.UrlLocalizer.OutgoingUrlFilters += delegate(string url, Uri currentRequestUrl)
{
Uri uri;
if (Uri.TryCreate(url, UriKind.Absolute, out uri)
|| Uri.TryCreate(currentRequestUrl, url, out uri))
{
if (uri.LocalPath.IndexOf("/api", StringComparison.OrdinalIgnoreCase) != -1)
return false;
}
return true;
};
things to works as expected.
Hi Martin
thanks for your response. Still have the trouble, and hope you could give me a few pointers.
I just forked v2.1.4.0, build it, updated dll's in asp.net mvc project (tested it works), read the documentation and added your code suggestion (i18n.UrlLocalizer.OutgoingUrlFilters). However, I'm still getting the re-direct behaviour.
If I comment out the following in web.config the GET api method runs correctly:
<system.web><httpModules>
<add name="i18n.LocalizingModule" type="i18n.LocalizingModule, i18n" />
<system.webServer><modules>
<add name="i18n.LocalizingModule" type="i18n.LocalizingModule, i18n" />
In Global.asax.cs
in protected void Application_Start()
I have adding the following code:
i18n.UrlLocalizer.OutgoingUrlFilters += delegate(string url, Uri currentRequestUrl)
{
Uri uri;
if (Uri.TryCreate(url, UriKind.Absolute, out uri)
|| Uri.TryCreate(currentRequestUrl, url, out uri))
{
if (uri.LocalPath.IndexOf("/api", StringComparison.OrdinalIgnoreCase) != -1)
return false;
}
return true;
};
The code (i18n.UrlLocalizer.OutgoingUrlFilters in Application_Start()
) is never touched when calling the GET api method, and I'm still getting the re-direct behaviour:
Api methods:
public class SystemController : BaseApiController
{
[Route("api/v1/system/GetApiVersion"), HttpPost]
public HttpResponseMessage GetApiVersion()
{
return Request.CreateResponse(HttpStatusCode.OK, new
{
Version = Constants.ApiVersion
});
}
[Route("api/v1/system/GetApiVersion2"), HttpGet]
public HttpResponseMessage GetApiVersion2()
{
return Request.CreateResponse(HttpStatusCode.OK, new
{
Version = Constants.ApiVersion
});
}
}
Fiddler GET call (the one failing):
GET http://localhost:50708/api/v1/system/GetApiVersion2 HTTP/1.1
Host: localhost:50708
Fiddler response to GET call:
# Result Protocol Host URL Body Caching Content-Type Process Comments Custom
8 302 HTTP localhost:50708 /api/v1/system/GetApiVersion2 0 fiddler:9088
9 404 HTTP localhost:50708 /en/v1/system/GetApiVersion2 3.204 private text/html; charset=utf-8 fiddler:9088
Fiddler POST call (works):
POST http://localhost:50708/api/v1/system/GetApiVersion HTTP/1.1
Host: localhost:50708
Fiddler response to POST call:
# Result Protocol Host URL Body Caching Content-Type Process Comments Custom
42 200 HTTP localhost:50708 /api/v1/system/GetApiVersion 13 no-cache; Expires: -1 application/json; charset=utf-8
the i18n web.config -> appSettings keys:
<add key="i18n.DirectoriesToScan" value="" />
<!--Rel to web.config file-->
<add key="i18n.WhiteList" value="*.cs;*.cshtml;*.sitemap;*.js" />
<add key="i18n.NuggetBeginToken" value="[#[" />
<add key="i18n.NuggetEndToken" value="]#]" />
Hmm, I can't see anything that you're doing wrong.
If I set a breakpoint in my OutgoingUrlFilter delegate then debug a request, here's my call stack when the BP get's hit:
Lynx.dll!Lynx.MvcApplication.Application_Start.AnonymousMethod__2(string url = "/Scripts/modernizr-2.6.2.js", System.Uri currentRequestUrl = {System.Uri}) C#
> i18n.dll!i18n.UrlLocalizer.FilterOutgoing(string url = "/Scripts/modernizr-2.6.2.js", System.Uri currentRequestUrl = {System.Uri}) C#
i18n.dll!i18n.EarlyUrlLocalizer.LocalizeUrl(System.Web.HttpContextBase context = {System.Web.HttpContextWrapper}, string url = "/Scripts/modernizr-2.6.2.js", string langtag = "en-GB", System.Uri requestUrl = {System.Uri}, bool incomingUrl = false) C#
i18n.dll!i18n.EarlyUrlLocalizer.ProcessOutgoing.AnonymousMethod__0(System.Text.RegularExpressions.Match match = {System.Text.RegularExpressions.Match}) C#
System.dll!System.Text.RegularExpressions.RegexReplacement.Replace(System.Text.RegularExpressions.MatchEvaluator evaluator = {Method = {System.Reflection.RuntimeMethodInfo}}, System.Text.RegularExpressions.Regex regex, string input, int count = -1, int startat)
System.dll!System.Text.RegularExpressions.Regex.Replace(string input, System.Text.RegularExpressions.MatchEvaluator evaluator, int count, int startat)
System.dll!System.Text.RegularExpressions.Regex.Replace(string input, System.Text.RegularExpressions.MatchEvaluator evaluator)
i18n.dll!i18n.EarlyUrlLocalizer.ProcessOutgoing(string entity, string langtag = "en-GB", System.Web.HttpContextBase context = {System.Web.HttpContextWrapper}) C#
i18n.dll!i18n.ResponseFilter.Flush() C#
System.Web.dll!System.Web.HttpWriter.FilterIntegrated(bool finalFiltering = true, System.Web.Hosting.IIS7WorkerRequest wr)
System.Web.dll!System.Web.HttpResponse.FilterOutput()
System.Web.dll!System.Web.HttpApplication.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step = {System.Web.HttpApplication.CallFilterExecutionStep}, ref bool completedSynchronously = false)
System.Web.dll!System.Web.HttpApplication.PipelineStepManager.ResumeSteps(System.Exception error)
System.Web.dll!System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext context, System.AsyncCallback cb)
System.Web.dll!System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest wr = {System.Web.Hosting.IIS7WorkerRequest}, System.Web.HttpContext context = {System.Web.HttpContext})
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext = 194144004, System.IntPtr moduleData, int flags)
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags)
[Native to Managed Transition]
[Managed to Native Transition]
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags)
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags)
[Appdomain Transition]
If you can try setting breakpoints back along that chain you might be able to see where it goes wrong.
Ah yes, sorry, I also have a matching IncomingUrlFilters delegate:
i18n.UrlLocalizer.IncomingUrlFilters += delegate(Uri url)
{
if (url.LocalPath.IndexOf("/Api", StringComparison.OrdinalIgnoreCase) != -1) {
return false; }
if (url.LocalPath.IndexOf("xdomain", StringComparison.OrdinalIgnoreCase) != -1) {
return false; }
//
return true;
};
Thanks. As mentioned, when I use:
i18n.UrlLocalizer.IncomingUrlFilters += delegate(Uri url)
{
if (url.LocalPath.Contains("/api"))
return false;
return true;
};
my Api GET calls (http://domain/api/xxx) works just fine.
I'm adding web api 2 methods to a asp.net mvc 5 project, however, when i18n is enabled, my GET method calls are being redirected to selected country. For example: http://xxx/api/v1/system/getappversion2 is redirected to http://xxx/en/v1/system/getappversion2
My POST methods are called correctly with or without i18n.
Must I somewhere exclude api from the i18n logic?
Two examples: [Route("api/v1/system/getappversion"), HttpPost] public HttpResponseMessage GetAppVersion() { const int appVersion = 1; return Request.CreateResponse(HttpStatusCode.OK, new { AppVersion = appVersion }); }
[Route("api/v1/system/getappversion2"), HttpGet] public HttpResponseMessage GetAppVersion2() { const int appVersion = 1; return Request.CreateResponse(HttpStatusCode.OK, new { AppVersion = appVersion }); }
GetAppVersion (POST) work with or without i18n. GetAppVersion2 (GET) only works without i18n. When i18n api/v1/system/getappversion2 is re-directed to en/v1/system/getappversion2
In Fiddler I get:
Terse summary GET http://localhost:50708/api/v1/system/getappversion2 302 Redirect to /en/v1/system/getappversion2
GET http://localhost:50708/en/v1/system/getappversion2 404 Not Found (text/html)
Full summary Result Protocol Host URL Body Caching Content-Type Process Comments Custom
1 302 HTTP localhost:50708 /api/v1/system/getappversion2 0 fiddler:9088
2 404 HTTP localhost:50708 /en/v1/system/getappversion2 3.204 private text/html; charset=utf-8 fiddler:9088
Headers only GET http://localhost:50708/api/v1/system/getappversion2 HTTP/1.1 User-Agent: Fiddler Host: localhost:50708
HTTP/1.1 302 Moved Temporarily Location: /en/v1/system/getappversion2 X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcTW9ydGVuXFByb2plY3RzXE5TQVxJblN0b3JlRXhjZWxsZW5jZVxzcmNcSW5TdG9yZUV4Y2VsbGVuY2UuV2ViXGFwaVx2MVxzeXN0ZW1cZ2V0YXBwdmVyc2lvbjI=?= X-Powered-By: ASP.NET X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval' https://_.googleapis.com https://_.gstatic.com https://www.google-analytics.com https://*.google.com; frame-ancestors 'self' https://www.google.com Date: Wed, 08 Jul 2015 19:40:56 GMT Content-Length: 0
GET http://localhost:50708/en/v1/system/getappversion2 HTTP/1.1 User-Agent: Fiddler Host: localhost:50708
HTTP/1.1 404 Not Found Cache-Control: private Content-Type: text/html; charset=utf-8 X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcTW9ydGVuXFByb2plY3RzXE5TQVxJblN0b3JlRXhjZWxsZW5jZVxzcmNcSW5TdG9yZUV4Y2VsbGVuY2UuV2ViXHYxXHN5c3RlbVxnZXRhcHB2ZXJzaW9uMg==?= X-Powered-By: ASP.NET X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval' https://_.googleapis.com https://_.gstatic.com https://www.google-analytics.com https://*.google.com; frame-ancestors 'self' https://www.google.com Date: Wed, 08 Jul 2015 19:40:56 GMT Content-Length: 3204