London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

Routing Segment Validator

Vote:
0

Hi,

When I want to publish a page update, I get a message that:

Something went wrong

  • "Name in URL" with value "name" is already in use by "name"
  • "Simple address" with value "name" is already in use by "name"

Code analysis may indicate that the validator searches all sites which is not a good solution, since the change concerns one and a specific site.

It seems the metod in class DefaultUrlSegmentLocator should also populate the SiteID in SimpleAddressResolveContext ??

private ContentReference FindCollidingSimpleAddressOnSite(
  ContentReference contentLink,
  string urlSegment,
  string language,
  SiteDefinition sitedef)
{
  Uri uri = DefaultUrlSegmentLocator.ResolveLanguageUrl(sitedef, language);
  string url;
  if (uri != (Uri) null)
  {
    Uri baseUri = uri;
    string absolute = this._virtualPathResolver.ToAbsolute("~/" + urlSegment);
    int length1 = absolute.Length;
    int startIndex = 1;
    int num = startIndex;
    int length2 = length1 - num;
    string relativeUri = absolute.Substring(startIndex, length2);
    url = new Uri(baseUri, relativeUri).ToString();
  }
  else
    url = (sitedef.SiteUrl != (Uri) null ? sitedef.SiteUrl.OriginalString : DefaultUrlSegmentLocator.AppendTrailingSlash(this._hostingEnvironment.WebRootVirtualPath)) + urlSegment;
  SimpleAddressResolveContext simpleAddressContext = new SimpleAddressResolveContext()
  {
    UseStrictLanguageMatch = this._options.RequireLanguageMatch
  };
  if (language != null)
    simpleAddressContext.Language = CultureInfo.GetCultureInfo(language);
  SimpleAddressResolveResult addressResolveResult = this._simpleAddressResolver.Resolve(new UrlBuilder(url), simpleAddressContext);
  return !ContentReference.IsNullOrEmpty(addressResolveResult?.ContentLink) && !contentLink.CompareToIgnoreWorkID(addressResolveResult.ContentLink) && !contentLink.CompareToIgnoreWorkID(addressResolveResult.OriginalContentLink) && (string.IsNullOrEmpty(language) || uri == (Uri) null || string.Equals(language, addressResolveResult.Language?.Name, StringComparison.OrdinalIgnoreCase)) && string.Equals(urlSegment, addressResolveResult.SimpleAddress, StringComparison.OrdinalIgnoreCase) && string.Equals(language, addressResolveResult.Language?.Name, StringComparison.OrdinalIgnoreCase) ? addressResolveResult.ContentLink : (ContentReference) null;
}

which will affect the search within only one site in the method FindBestMatch in class SimpleAddress ->  if (simpleAddressContext.SiteId.HasValue)

    private SimpleAddressResolveResult FindBestMatch(
      SimpleAddressResolveContext simpleAddressContext,
      object[] pageRefsHolder,
      string path)
    {
      IList<int> source1 = (IList<int>) pageRefsHolder[0];
      IList<string> languages = (IList<string>) pageRefsHolder[1];
      IList<string> urls = (IList<string>) pageRefsHolder[2];
      Func<int, int, SimpleAddressResolveResult> selector = (Func<int, int, SimpleAddressResolveResult>) ((id, index) =>
      {
        SimpleAddressResolveResult bestMatch = new SimpleAddressResolveResult();
        bestMatch.ContentLink = new ContentReference(id);
        bestMatch.Language = CultureInfo.GetCultureInfo(languages[index]);
        string str = urls[index];
        int length1 = str.Length;
        int startIndex = 2;
        int num = startIndex;
        int length2 = length1 - num;
        bestMatch.SimpleAddress = str.Substring(startIndex, length2);
        return bestMatch;
      });
      IEnumerable<SimpleAddressResolveResult> source2 = source1.Select<int, SimpleAddressResolveResult>(selector).Where<SimpleAddressResolveResult>((Func<SimpleAddressResolveResult, bool>) (x => SimpleAddress.IsMatchSegmentBySegment(path, x.SimpleAddress)));
      if (simpleAddressContext.SiteId.HasValue)
        source2 = source2.Where<SimpleAddressResolveResult>((Func<SimpleAddressResolveResult, bool>) (x =>
        {
          SiteDefinition byContent = this._siteDefinitionResolver.GetByContent(x.ContentLink, false);
          return byContent == null || byContent.Id == simpleAddressContext.SiteId.Value;
        }));
      if (simpleAddressContext.Language != null && this._routingOptions.StrictLanguageRouting)
        source2 = source2.Where<SimpleAddressResolveResult>((Func<SimpleAddressResolveResult, bool>) (x => x.Language.Name == simpleAddressContext.Language.Name || this.ExistLanguageFallback(x.ContentLink, simpleAddressContext.Language.Name, x.Language.Name)));
      IOrderedEnumerable<SimpleAddressResolveResult> source3 = source2.OrderByDescending<SimpleAddressResolveResult, int>((Func<SimpleAddressResolveResult, int>) (x => x.SimpleAddress.Length));
      if (simpleAddressContext.Language != null)
        source3 = source3.ThenByDescending<SimpleAddressResolveResult, bool>((Func<SimpleAddressResolveResult, bool>) (x => x.Language.Name == simpleAddressContext.Language.Name || this.ExistLanguageFallback(x.ContentLink, simpleAddressContext.Language.Name, x.Language.Name)));
      if (this._contentLanguageAccessor.Language != null)
        source3 = source3.ThenByDescending<SimpleAddressResolveResult, bool>((Func<SimpleAddressResolveResult, bool>) (x => x.Language.Name.Equals(this._contentLanguageAccessor.Language.Name, StringComparison.OrdinalIgnoreCase)));
      return simpleAddressContext.Language != null ? source3.FirstOrDefault<SimpleAddressResolveResult>((Func<SimpleAddressResolveResult, bool>) (sc =>
      {
        IContentLoader contentLoader = this._contentLoader;
        ContentReference contentLink = sc.ContentLink;
        LoaderOptions settings = new LoaderOptions();
        settings.Add<LanguageLoaderOption>(LanguageLoaderOption.Fallback(simpleAddressContext.Language));
        IContent content;
        ref IContent local = ref content;
        return contentLoader.TryGet<IContent>(contentLink, settings, out local);
      })) : source3.FirstOrDefault<SimpleAddressResolveResult>();
    }

Can that be considered a bug or intended solution?

#292450
Edited, Nov 30, 2022 17:06
Vote:
0

Are you on CMS 12 as I believe the bug was raised in CMS11 (11.11.1) but than fixed in version 11.11.2. Please see here : https://world.optimizely.com/documentation/Release-Notes/ReleaseNote/?releaseNoteId=CMS-13349 

#292475
Nov 30, 2022 21:35
Vote:
0

yes I have EpiServer.CMS 12.13.1

#292513
Dec 01, 2022 6:58
Vote:
0

I will forward this question to our content-framework (former CMS Core) team, will get back to you 

#292514
Dec 01, 2022 7:55
Vote:
0

@Quan Thx, I have the same sitution for:

  • "Name in URL" 
  • "Simple address" 
#292515
Dec 01, 2022 8:21
Vote:
0

Thankyou for reporting the issue, It seems it is a bug and we will looked into it a.s.a.p.

#292573
Dec 02, 2022 9:45
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.