@@ -97,8 +97,14 @@ protected override void NavigateToCore(string uri, NavigationOptions options)
9797 }
9898 else
9999 {
100+ if ( ! IsInternalUri ( absoluteUriString ) )
101+ {
102+ // it's an external navigation, avoid Uri validation exception
103+ BaseUri = GetBaseUriFromAbsoluteUri ( absoluteUriString ) ;
104+ }
100105 Uri = absoluteUriString ;
101106 NotifyLocationChanged ( isInterceptedLink : false ) ;
107+ return ;
102108 }
103109 }
104110
@@ -134,6 +140,44 @@ async Task PerformNavigationAsync()
134140 }
135141 }
136142
143+ private bool IsInternalUri ( string uri )
144+ {
145+ var normalizedBaseUri = NormalizeBaseUri ( BaseUri ) ;
146+ return uri . StartsWith ( normalizedBaseUri , StringComparison . OrdinalIgnoreCase ) ;
147+ }
148+
149+ private static string GetBaseUriFromAbsoluteUri ( string absoluteUri )
150+ {
151+ // Find the position of the first single slash after the scheme (e.g., "https://")
152+ var schemeDelimiterIndex = absoluteUri . IndexOf ( "://" , StringComparison . Ordinal ) ;
153+ if ( schemeDelimiterIndex == - 1 )
154+ {
155+ throw new ArgumentException ( $ "The provided URI '{ absoluteUri } ' is not a valid absolute URI.") ;
156+ }
157+
158+ // Find the end of the authority section (e.g., "https://example.com/")
159+ var authorityEndIndex = absoluteUri . IndexOf ( '/' , schemeDelimiterIndex + 3 ) ;
160+ if ( authorityEndIndex == - 1 )
161+ {
162+ // If no slash is found, the entire URI is the authority (e.g., "https://example.com")
163+ return NormalizeBaseUri ( absoluteUri + "/" ) ;
164+ }
165+
166+ // Extract the base URI up to the authority section
167+ return NormalizeBaseUri ( absoluteUri . Substring ( 0 , authorityEndIndex + 1 ) ) ;
168+ }
169+
170+ private static string NormalizeBaseUri ( string baseUri )
171+ {
172+ var lastSlashIndex = baseUri . LastIndexOf ( '/' ) ;
173+ if ( lastSlashIndex >= 0 )
174+ {
175+ baseUri = baseUri . Substring ( 0 , lastSlashIndex + 1 ) ;
176+ }
177+
178+ return baseUri ;
179+ }
180+
137181 /// <inheritdoc />
138182 public override void Refresh ( bool forceReload = false )
139183 {
@@ -148,6 +192,7 @@ public override void Refresh(bool forceReload = false)
148192 {
149193 Uri = absoluteUriString ;
150194 NotifyLocationChanged ( isInterceptedLink : false ) ;
195+ return ;
151196 }
152197 }
153198
0 commit comments