Ejemplo n.º 1
0
        /// <summary>
        /// Gets canonical url of current resource.
        /// </summary>
        /// <returns>The canonical url of current resource.</returns>
        public virtual Uri GetCanonicalUrl()
        {
            if (this.canonicalUrl != null)
            {
                return(this.canonicalUrl);
            }

            // canonicalUrl = HasNonComputedId
            if (this.resource.HasNonComputedId)
            {
                return(this.canonicalUrl = this.resource.NonComputedId);
            }

            // Compute canonicalUrl from parent canonicalUrl
            var parent = this.ParentMetadataBuilder as ODataConventionalResourceMetadataBuilder;

            if (this.NameAsProperty != null &&
                parent != null &&
                parent.GetCanonicalUrl() != null)
            {
                // If parent is collection of complex, the canonical url for this resource should be null.
                if (parent.IsFromCollection && !(parent is ODataConventionalEntityMetadataBuilder))
                {
                    return(this.canonicalUrl = null);
                }

                // canonicalUrl = parentCanonicalUrl[/typeCast]/propertyName
                // Different from edit url and read url, canonical url only needs type cast when the property is defined on derived type.
                this.canonicalUrl = parent.GetCanonicalUrl();

                IODataResourceTypeContext typeContext = parent.ResourceMetadataContext.TypeContext;

                if (parent.ResourceMetadataContext.ActualResourceTypeName != typeContext.ExpectedResourceTypeName)
                {
                    // Do not append type cast if we know that the navigation property is in base type, not in derived type.
                    ODataResourceTypeContext.ODataResourceTypeContextWithModel typeContextWithModel =
                        typeContext as ODataResourceTypeContext.ODataResourceTypeContextWithModel;
                    if (typeContextWithModel == null ||
                        typeContextWithModel.ExpectedResourceType.FindProperty(
                            this.NameAsProperty) == null)
                    {
                        this.canonicalUrl = this.UriBuilder.AppendTypeSegment(canonicalUrl,
                                                                              parent.ResourceMetadataContext.ActualResourceTypeName);
                    }
                }

                this.canonicalUrl = new Uri(string.Concat(this.canonicalUrl, "/", this.NameAsProperty), UriKind.RelativeOrAbsolute);
            }
            else
            {
                if (this.ODataUri != null && this.ODataUri.Path.Count != 0)
                {
                    this.canonicalUrl = this.ODataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);
                }
            }

            return(this.canonicalUrl);
        }
Ejemplo n.º 2
0
        private bool TryComputeIdFromParent(out Uri uri)
        {
            try
            {
                ODataConventionalResourceMetadataBuilder parent = this.ParentMetadataBuilder as ODataConventionalResourceMetadataBuilder;
                if (parent != null && parent != this)
                {
                    // Get the parent canonical url
                    uri = parent.GetCanonicalUrl();

                    if (uri != null)
                    {
                        // And append cast (if needed).
                        // A cast segment if the navigation property is defined on a type derived from the type expected.
                        IODataResourceTypeContext typeContext = parent.ResourceMetadataContext.TypeContext;

                        if (parent.ResourceMetadataContext.ActualResourceTypeName != typeContext.ExpectedResourceTypeName)
                        {
                            // Do not append type cast if we know that the navigation property is in base type, not in derived type.
                            ODataResourceTypeContext.ODataResourceTypeContextWithModel typeContextWithModel =
                                typeContext as ODataResourceTypeContext.ODataResourceTypeContextWithModel;
                            if (typeContextWithModel == null ||
                                typeContextWithModel.ExpectedResourceType.FindProperty(
                                    this.ResourceMetadataContext.TypeContext.NavigationSourceName) == null)
                            {
                                uri = new Uri(UriUtils.EnsureTaillingSlash(uri),
                                              parent.ResourceMetadataContext.ActualResourceTypeName);
                            }
                        }

                        return(true);
                    }
                }
            }
            catch (ODataException)
            {
            }

            uri = null;
            return(false);
        }