Routing Segment Validator

Vote:
 

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:
 

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:
 

yes I have EpiServer.CMS 12.13.1

#292513
Dec 01, 2022 6:58
Vote:
 

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:
 

@Quan Thx, I have the same sitution for:

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

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.