public string GetMsdnUrl (string id) { if (cachedMsdnUrls.ContainsKey(id)) return (String.Format(urlFormat, locale, cachedMsdnUrls[id])); if (msdnService == null) return(null); getContentRequest msdnRequest = new getContentRequest(); msdnRequest.contentIdentifier = "AssetId:" + id; msdnRequest.locale = locale; string endpoint = null; try { getContentResponse msdnResponse = msdnService.GetContent(msdnRequest); endpoint = msdnResponse.contentId; } catch (WebException) { msdnService = null; } catch (SoapException) { // lookup failed } cachedMsdnUrls[id] = endpoint; if (String.IsNullOrEmpty(endpoint)) { return (null); } else { return (String.Format(urlFormat, locale, endpoint)); } }
public static string GetDocFromMTPS(string shortId) { try { if (proxy == null) { proxy = new ContentServicePortTypeClient(); } var request = new getContentRequest { contentIdentifier = shortId, locale = "en-us", version = "VS.85", requestedDocuments = new[] { new requestedDocument() { type = documentTypes.primary, selector = "Mtps.Xhtml" } } }; var response = proxy.GetContent(new appId() { value = "Sandcastle" }, request); if (response.primaryDocuments[0].Any != null) { return(response.primaryDocuments[0].Any.OuterXml); } } catch (Exception ex) { Logger.Warning("MTPS error for id {0} : {1}", shortId, ex.Message); } return(string.Empty); }
private async Task <string> GetDocFromMTPS(string shortId) { try { if (proxy == null) { proxy = new ContentServicePortTypeClient(ContentServicePortTypeClient.EndpointConfiguration.ContentService); } var request = new getContentRequest { contentIdentifier = shortId, locale = "en-us", version = "VS.85", requestedDocuments = new[] { new requestedDocument { type = documentTypes.primary, selector = "Mtps.Xhtml" } } }; var response = await Task.Run(() => proxy.GetContent(new appId { value = "Sandcastle" }, request)); if (response.primaryDocuments[0].Any != null) { return(response.primaryDocuments[0].Any.OuterXml); } } catch (Exception) { return(string.Empty); } return(string.Empty); }
// Use the standard root node to get a list of locales available. static public SortedDictionary <string, string> GetLocales() { SortedDictionary <string, string> locales = new SortedDictionary <string, string>(); getContentRequest request = new getContentRequest(); ContentService proxy = new ContentService(); getContentResponse response; request.contentIdentifier = rootContentItem.contentId; request.locale = "en-US"; // Now required otherwise an exception. try { response = proxy.GetContent(request); } catch { locales.Add("English (United States)", "en-us"); return(locales); } foreach (availableVersionAndLocale av in response.availableVersionsAndLocales) { // Use the DisplayName as the key instead of the locale because // that's how we want the collection sorted. string displayName = new CultureInfo(av.locale).DisplayName; if (locales.ContainsKey(displayName) == false) { locales.Add(displayName, av.locale.ToLower()); } } return(locales); }
public getContentResponse GetContent([System.Xml.Serialization.XmlElementAttribute(Namespace = "urn:msdn-com:public-content-syndication")] getContentRequest getContentRequest) { object[] results = this.Invoke("GetContent", new object[] { getContentRequest }); return((getContentResponse)(results[0])); }
public Uri ResolveAssetId(string assetId, Version version) { string ret; if (this._cachedMsdnUrls.TryGetValue(assetId, out ret)) { if (ret != null) return new Uri(string.Format(UrlFormat, this._locale, ret)); return null; } // filter out non-MS namespaces string name = assetId.Substring(2); if (!name.StartsWith("System", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("Accessibility", StringComparison.OrdinalIgnoreCase)) { return null; } getContentRequest msdnRequest = new getContentRequest(); msdnRequest.contentIdentifier = "AssetId:" + assetId; msdnRequest.locale = this._locale; string endpoint = null; ContentServicePortTypeClient client = new ContentServicePortTypeClient(_msdnBinding, _msdnEndpoint); try { getContentResponse msdnResponse = client.GetContent(new appId {value = "LostDoc"}, msdnRequest); endpoint = msdnResponse.contentId; } catch (FaultException<mtpsFaultDetailType>) { } finally { try { client.Close(); } catch { client.Abort(); } ((IDisposable)client).Dispose(); } this._cachedMsdnUrls.TryAdd(assetId, endpoint); if (string.IsNullOrEmpty(endpoint)) return null; return new Uri(string.Format(UrlFormat, this._locale, endpoint)); }
/// <remarks/> public void GetContentAsync(getContentRequest getContentRequest, object userState) { if ((this.GetContentOperationCompleted == null)) { this.GetContentOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetContentOperationCompleted); } this.InvokeAsync("GetContent", new object[] { getContentRequest }, this.GetContentOperationCompleted, userState); }
private static Tuple<string, string> GetContentIdAndAlias(string assetId, string version = "VS.110", string locale = "en-us") { var request = new getContentRequest { contentIdentifier = assetId, locale = locale, version = version }; // get response var response = ContentServiceClient.GetContent(new appId(), request); return Tuple.Create(response.contentId, response.contentAlias); }
public Uri ResolveAssetId(string assetId, Version version) { if (this._cachedMsdnUrls.ContainsKey(assetId) && this._cachedMsdnUrls[assetId] != null) return new Uri(string.Format(UrlFormat, this._locale, this._cachedMsdnUrls[assetId])); getContentRequest msdnRequest = new getContentRequest(); msdnRequest.contentIdentifier = "AssetId:" + assetId; msdnRequest.locale = this._locale; string endpoint = null; Binding msdnBinding = new BasicHttpBinding(BasicHttpSecurityMode.None); EndpointAddress msdnEndpoint = new EndpointAddress("http://services.msdn.microsoft.com/ContentServices/ContentService.asmx"); ContentServicePortTypeClient client = new ContentServicePortTypeClient(msdnBinding, msdnEndpoint); try { getContentResponse msdnResponse = client.GetContent(new appId {value = "LostDoc"}, msdnRequest); endpoint = msdnResponse.contentId; } catch (FaultException<mtpsFaultDetailType>) { } finally { try { client.Close(); } catch { client.Abort(); } if (client is IDisposable) ((IDisposable)client).Dispose(); } this._cachedMsdnUrls[assetId] = endpoint; if (string.IsNullOrEmpty(endpoint)) { return null; } else { return new Uri(string.Format(UrlFormat, this._locale, endpoint)); } }
private static Tuple <string, string> GetContentIdAndAlias(string assetId, string version = "VS.110", string locale = "en-us") { var request = new getContentRequest { contentIdentifier = assetId, locale = locale, version = version }; // get response var response = ContentServiceClient.GetContent(new appId(), request); return(Tuple.Create(response.contentId, response.contentAlias)); }
public MainWindow() { InitializeComponent(); // Use the ContentService (web service) // Set up a request object getContentRequest request = new getContentRequest(); request.contentIdentifier = "abhtw0f1"; // Create the client ContentServicePortTypeClient client = new ContentServicePortTypeClient(); this.DataContext = client.GetContent(new appId(), request); }
// Handler for the Windows Loaded event void OnLoad(object sender, RoutedEventArgs e) { // 2. Set up the request object // To use the MSTP web service, we need to configure and send a request // In this example, we create a simple request that has the ID of the XmlReader.Read method page getContentRequest request = new getContentRequest(); request.contentIdentifier = "abhtw0f1"; // 3. Create the proxy ContentService proxy = new ContentService(); // 4. Call the web service method and set the DataContext of the Window // (GetContent returns an object of type getContentResponse) this.DataContext = proxy.GetContent(request); }
/// <summary> /// Finds a URL from MSDN documentation. /// </summary> /// <param name="assetId">The asset id in the form "T:System.String"</param> /// <returns>A URL to MSDN or null if no URL was found</returns> public string FindUrl(string assetId) { // Only look for T:System. if (assetId.Length < 3 || !assetId.Substring(2).StartsWith("System.") || IsDisabled) { return(null); } string contentId; if (!_mapAssetIdToContentId.TryGetValue(assetId, out contentId)) { try { Logger.Message("Get MSDN URL for id [{0}]", assetId); var request = new getContentRequest { contentIdentifier = "AssetId:" + HttpUtility.UrlEncode(assetId), locale = Locale }; var appId = new appId() { value = AppId }; var response = msdnClient.GetContent(appId, request); contentId = response.contentId; } catch (EndpointNotFoundException endpointNotFound) { Logger.Warning("Unable to connect to MTPS service. MSDN resolver disabled : {0}", endpointNotFound.Message); IsDisabled = true; } catch (Exception ex) { Logger.Warning("Error while getting MSDN URL [{0}] : {1}", assetId, ex.Message); } _mapAssetIdToContentId[assetId] = contentId; SaveCacheToDisk(); } if (string.IsNullOrEmpty(contentId)) { return(null); } return(string.Format(MsdnUrlFormat, Locale, contentId)); }
public string GetMsdnUrl(string id) { if (cachedMsdnUrls.ContainsKey(id)) { return(String.Format(urlFormat, locale, cachedMsdnUrls[id])); } if (msdnService == null) { return(null); } getContentRequest msdnRequest = new getContentRequest(); msdnRequest.contentIdentifier = "AssetId:" + id; msdnRequest.locale = locale; string endpoint = null; try { getContentResponse msdnResponse = msdnService.GetContent(msdnRequest); endpoint = msdnResponse.contentId; } catch (WebException) { msdnService = null; } catch (SoapException) { // lookup failed } cachedMsdnUrls[id] = endpoint; if (String.IsNullOrEmpty(endpoint)) { return(null); } else { return(String.Format(urlFormat, locale, endpoint)); } }
private static Toc GetNamespaceToc(string assetId, string version = "VS.110", string locale = "en-us") { var docType = documentTypes.primary; var docSelector = "Mtps.Toc"; // prepare request var request = new getContentRequest { contentIdentifier = assetId, locale = locale, version = version, requestedDocuments = new[] { new requestedDocument { type = docType, selector = docSelector } } }; // get response var response = ContentServiceClient.GetContent(new appId(), request); // extract primary document foreach (var doc in response.primaryDocuments) { if (doc.primaryFormat == docSelector) { var tocElement = doc.Any; var serializer = new XmlSerializer(typeof(Toc)); var reader = new XmlNodeReader(tocElement); return((Toc)serializer.Deserialize(reader)); } } return(null); }
/// <summary> /// Finds an URL from MSDN documentation. /// </summary> /// <param name="assetId">The asset id in the form "T:System.String"</param> /// <returns>An url to MSDN or null if no url was found</returns> public string FindUrl(string assetId) { // Only look for T:System. if (assetId.Length < 3 || !assetId.Substring(2).StartsWith("System.") || IsDisabled) return null; string contentId; if (!_mapAssetIdToContentId.TryGetValue(assetId, out contentId)) { try { Logger.Message("Get MSDN URL for id [{0}]", assetId); var request = new getContentRequest { contentIdentifier = "AssetId:" + HttpUtility.UrlEncode(assetId), locale = Locale }; var appId = new appId() { value = AppId }; var response = msdnClient.GetContent(appId, request); contentId = response.contentId; } catch (EndpointNotFoundException endpointNotFound) { Logger.Warning("Unable to connect to MTPS service. Msnd resolver disabled : {0}", endpointNotFound.Message); IsDisabled = true; } catch (Exception ex) { Logger.Warning("Error while getting msdn url [{0}] : {1}", assetId, ex.Message); } _mapAssetIdToContentId[assetId] = contentId; SaveCacheToDisk(); } if (string.IsNullOrEmpty(contentId)) return null; return string.Format(MsdnUrlFormat, Locale, contentId); }
public static string GetDocFromMTPS(string shortId) { try { if (proxy == null) proxy = new ContentServicePortTypeClient(); var request = new getContentRequest { contentIdentifier = shortId, locale = "en-us", version = "VS.85", requestedDocuments = new[] { new requestedDocument() { type = documentTypes.primary, selector = "Mtps.Xhtml" } } }; var response = proxy.GetContent(new appId() { value = "Sandcastle" }, request); if (response.primaryDocuments[0].Any != null) return response.primaryDocuments[0].Any.OuterXml; } catch (Exception ex) { Logger.Warning("MTPS error for id {0} : {1}", shortId, ex.Message); } return string.Empty; }
/// <remarks/> public void GetContentAsync(getContentRequest getContentRequest, object userState) { if ((this.GetContentOperationCompleted == null)) { this.GetContentOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetContentOperationCompleted); } this.InvokeAsync("GetContent", new object[] { getContentRequest}, this.GetContentOperationCompleted, userState); }
/// <remarks/> public void GetContentAsync(getContentRequest getContentRequest) { this.GetContentAsync(getContentRequest, null); }
// Added the loadFailSafe optimization public void Load(bool loadImages, bool loadFailSafe) { getContentRequest request = new getContentRequest(); request.contentIdentifier = contentIdentifier; request.locale = locale; request.version = collection + "." + version; List <requestedDocument> documents = new List <requestedDocument>(); requestedDocument document = new requestedDocument(); document.selector = "Mtps.Links"; document.type = documentTypes.common; documents.Add(document); document = new requestedDocument(); document.type = documentTypes.primary; document.selector = "Mtps.Toc"; documents.Add(document); document = new requestedDocument(); document.type = documentTypes.common; document.selector = "Mtps.Search"; documents.Add(document); document = new requestedDocument(); document.type = documentTypes.feature; document.selector = "Mtps.Annotations"; documents.Add(document); if (loadFailSafe == true) { document = new requestedDocument(); document.type = documentTypes.primary; document.selector = "Mtps.Failsafe"; documents.Add(document); } request.requestedDocuments = documents.ToArray(); ContentService proxy = new ContentService(); proxy.appIdValue = new appId(); proxy.appIdValue.value = application; getContentResponse response; try { response = proxy.GetContent(request); } catch { return; } if (validateAsFilename.Match(response.contentId).Success == true) { contentId = response.contentId; } else { throw (new BadContentIdException("ContentId contains illegal characters: [" + contentId + "]")); } numImages = response.imageDocuments.Length; foreach (common commonDoc in response.commonDocuments) { if (commonDoc.Any != null) { switch (commonDoc.commonFormat.ToLower()) { case "mtps.search": metadata = commonDoc.Any[0].OuterXml; break; case "mtps.links": links = commonDoc.Any[0].OuterXml; break; } } } foreach (primary primaryDoc in response.primaryDocuments) { if (primaryDoc.Any != null) { switch (primaryDoc.primaryFormat.ToLower()) { case "mtps.failsafe": xml = primaryDoc.Any.OuterXml; break; case "mtps.toc": toc = primaryDoc.Any.OuterXml; break; } } } foreach (feature featureDoc in response.featureDocuments) { if (featureDoc.Any != null) { if (featureDoc.featureFormat.ToLower() == "mtps.annotations") { annotations = featureDoc.Any[0].OuterXml; } } } // If we get no meta/search or wiki data, plug in NOP data because // we can't LoadXml an empty string nor pass null navigators to // the transform. if (string.IsNullOrEmpty(metadata) == true) { metadata = "<se:search xmlns:se=\"urn:mtpg-com:mtps/2004/1/search\" />"; } if (string.IsNullOrEmpty(annotations) == true) { annotations = "<an:annotations xmlns:an=\"urn:mtpg-com:mtps/2007/1/annotations\" />"; } if (loadImages == true) { requestedDocument[] imageDocs = new requestedDocument[response.imageDocuments.Length]; // Now that we know their names, we run a request with each image. for (int i = 0; i < response.imageDocuments.Length; i++) { imageDocs[i] = new requestedDocument(); imageDocs[i].type = documentTypes.image; imageDocs[i].selector = response.imageDocuments[i].name + "." + response.imageDocuments[i].imageFormat; } request.requestedDocuments = imageDocs; response = proxy.GetContent(request); foreach (image imageDoc in response.imageDocuments) { string imageFilename = imageDoc.name + "." + imageDoc.imageFormat; if (validateAsFilename.Match(imageFilename).Success == true) { images.Add(new Image(imageDoc.name, imageDoc.imageFormat, imageDoc.Value)); } else { throw (new BadImageNameExeception( "Image filename contains illegal characters: [" + imageFilename + "]")); } } } }
private getContentResponse CachedGetContentRequest(appId appId, getContentRequest request) { var requestKey = CreateGetContentRequestKey(request); var rawResult = Cache[requestKey] as getContentResponse; if (rawResult == null) { rawResult = Client.GetContent(appId, request); if (rawResult != null) Cache[requestKey] = rawResult; } return rawResult; }
public Uri ResolveAssetId(string assetId, Version version) { Uri ret; if (this._cachedMsdnUrls.TryGetValue(assetId, out ret)) return ret; // filter out non-MS namespaces string name = assetId.Substring(assetId.IndexOf(':') + 1); if (!name.StartsWith("System", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("Accessibility", StringComparison.OrdinalIgnoreCase)) { return null; } getContentRequest msdnRequest = new getContentRequest(); msdnRequest.contentIdentifier = "AssetId:" + assetId; msdnRequest.locale = this._locale; int retries = 3; do { ContentServicePortTypeClient client = new ContentServicePortTypeClient(_msdnBinding, _msdnEndpoint); try { getContentResponse msdnResponse = client.GetContent(new appId { value = "LostDoc" }, msdnRequest); if (msdnResponse.contentId != null) ret = new Uri(string.Format(UrlFormat, this._locale, msdnResponse.contentId)); break; } catch (TimeoutException) { // retry } catch (FaultException<mtpsFaultDetailType> fe) { // this is a fallback because MSDN doesn't have links for enumeration fields // so we assume that any unresolved field will be represented on it's parent type page if (assetId.StartsWith("F:")) { // TODO add logging for this string parentEnum = "T:" + assetId.Substring("F:".Length); parentEnum = parentEnum.Substring(0, parentEnum.LastIndexOf('.')); ret = this.ResolveAssetId(parentEnum, version); } break; } finally { try { client.Close(); } catch { client.Abort(); } ((IDisposable)client).Dispose(); } } while (--retries > 0); this._cachedMsdnUrls.TryAdd(assetId, ret); return ret; }
private static Toc GetNamespaceToc(string assetId, string version = "VS.110", string locale = "en-us") { var docType = documentTypes.primary; var docSelector = "Mtps.Toc"; // prepare request var request = new getContentRequest { contentIdentifier = assetId, locale = locale, version = version, requestedDocuments = new[] { new requestedDocument { type = docType, selector = docSelector } } }; // get response var response = ContentServiceClient.GetContent(new appId(), request); // extract primary document foreach (var doc in response.primaryDocuments) { if (doc.primaryFormat == docSelector) { var tocElement = doc.Any; var serializer = new XmlSerializer(typeof(Toc)); var reader = new XmlNodeReader(tocElement); return (Toc)serializer.Deserialize(reader); } } return null; }
private string CreateGetContentRequestKey(getContentRequest request) { return String.Format( "MTPS_GetContent({0},{1},{2},[{3}])", request.contentIdentifier, request.locale, request.version, String.Join(",",(request.requestedDocuments ?? Enumerable.Empty<requestedDocument>()).Select(d => String.Concat(d.type,d.selector))) ); }
/// <remarks/> public System.IAsyncResult BeginGetContent(getContentRequest getContentRequest, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("GetContent", new object[] { getContentRequest}, callback, asyncState); }
private XmlElement GetContent(string assetId) { var request = new getContentRequest { contentIdentifier = assetId, locale = Locale, version = Version, requestedDocuments = new [] { new requestedDocument { selector = "Mtps.Xhtml", type = documentTypes.primary } } }; var rawResult = CachedGetContentRequest(_appId, request); var bestNode = rawResult.primaryDocuments.FirstOrDefault(x => x.primaryFormat == "Mtps.Xhtml"); if (bestNode == null) return null; return bestNode.Any; }
public Uri ResolveAssetId(string assetId, Version version) { string ret; if (this._cachedMsdnUrls.TryGetValue(assetId, out ret)) { if (ret != null) { return(new Uri(string.Format(UrlFormat, this._locale, ret))); } return(null); } // filter out non-MS namespaces string name = assetId.Substring(2); if (!name.StartsWith("System", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("Accessibility", StringComparison.OrdinalIgnoreCase)) { return(null); } getContentRequest msdnRequest = new getContentRequest(); msdnRequest.contentIdentifier = "AssetId:" + assetId; msdnRequest.locale = this._locale; string endpoint = null; ContentServicePortTypeClient client = new ContentServicePortTypeClient(_msdnBinding, _msdnEndpoint); try { getContentResponse msdnResponse = client.GetContent(new appId { value = "LostDoc" }, msdnRequest); endpoint = msdnResponse.contentId; } catch (FaultException <mtpsFaultDetailType> ) { } finally { try { client.Close(); } catch { client.Abort(); } ((IDisposable)client).Dispose(); } this._cachedMsdnUrls.TryAdd(assetId, endpoint); if (string.IsNullOrEmpty(endpoint)) { return(null); } return(new Uri(string.Format(UrlFormat, this._locale, endpoint))); }
/// <remarks/> public System.IAsyncResult BeginGetContent(getContentRequest getContentRequest, System.AsyncCallback callback, object asyncState) { return(this.BeginInvoke("GetContent", new object[] { getContentRequest }, callback, asyncState)); }
//===================================================================== /// <summary> /// This is used to get the MSDN URL for the given .NET Framework member ID /// </summary> /// <param name="id">The member ID to look up</param> /// <returns>The MSDN URL for the member ID or null if not found</returns> public string GetMsdnUrl(string id) { string endPoint = null; bool success = false; if (msdnService != null && !cachedMsdnIds.TryGetValue(id, out endPoint)) { getContentRequest msdnRequest = new getContentRequest(); msdnRequest.contentIdentifier = "AssetId:" + id; msdnRequest.locale = this.Locale; try { getContentResponse msdnResponse = msdnService.GetContent(msdnRequest); endPoint = msdnResponse.contentId; success = true; } catch (WebException ex) { // Ignore failures, just turn off the service and note the last error for the caller msdnService.Dispose(); msdnService = null; this.DisabledReason = ex.Message; Exception innerEx = ex.InnerException; while (innerEx != null) { this.DisabledReason += "\r\n" + innerEx.Message; innerEx = innerEx.InnerException; } // Don't save changes to the cache this.CacheItemsAdded = false; } catch (SoapException ex) { if (ex.Message.IndexOf("content identifier not found", StringComparison.OrdinalIgnoreCase) != -1 || ex.Detail.OuterXml.IndexOf("mtpsContentIdentifierNotFound", StringComparison.Ordinal) != -1) { // Lookup failed (ID not found). Cache the result though since it isn't there. success = true; // For certain inherited explicitly implemented interface members, Microsoft is using // incorrect member IDs in the XML comments files and on the content service. If the // failed member ID looks like one of them, try using the broken ID for the look up. string brokenId = id; if (reDictionaryEII.IsMatch(brokenId)) { brokenId = reGenericEII.Replace(brokenId, "#I$1{TKey@TValue}#"); } else if (reGenericEII.IsMatch(brokenId)) { brokenId = reGenericEII.Replace(brokenId, "#I$1{T}#"); } // Don't bother if they are the same if (brokenId != id) { endPoint = this.GetMsdnUrl(brokenId); if (endPoint != null) { endPoint = endPoint.Substring(endPoint.LastIndexOf('/') + 1); } } } else { // Ignore failures, just turn off the service and note the last error for the caller msdnService.Dispose(); msdnService = null; this.DisabledReason = ex.Message; Exception innerEx = ex.InnerException; while (innerEx != null) { this.DisabledReason += "\r\n" + innerEx.Message; innerEx = innerEx.InnerException; } // Don't save changes to the cache this.CacheItemsAdded = false; } } // We'll cache the result but will only mark the cache as changed if successful so as not to // save null results from failures caused by issues other than not being found. cachedMsdnIds[id] = endPoint; if (success) { this.CacheItemsAdded = true; } } if (String.IsNullOrEmpty(endPoint)) { return(null); } return(String.Format(CultureInfo.InvariantCulture, "http://msdn2.microsoft.com/{0}/library/{1}", this.Locale, endPoint)); }
private XmlElement GetTocXmlElementRequest(string assetId, string version, string locale) { Contract.Requires(!String.IsNullOrEmpty(assetId)); var request = new getContentRequest { contentIdentifier = MtpsIdentifier.AppendAssetIdPrefixIfRequired(assetId), locale = locale, version = version, requestedDocuments = new[]{ new requestedDocument{ type = documentTypes.primary, selector = "Mtps.Toc" } } }; var rawResult = CachedGetContentRequest(_appId, request); if (rawResult == null) return null; var root = rawResult.primaryDocuments.SingleOrDefault(); if (null == root) return null; return root.Any; }