internal static void WriteRequestPreamble(TextWriter writer, string httpMethod, Uri uri) { writer.WriteLine("{0}: {1}", "Content-Type", "application/http"); writer.WriteLine("{0}: {1}", "Content-Transfer-Encoding", "binary"); writer.WriteLine(); writer.WriteLine("{0} {1} {2}", httpMethod, UriUtilsCommon.UriToString(uri), "HTTP/1.1"); }
Uri IODataUrlResolver.ResolveUrl(Uri baseUri, Uri payloadUri) { ExceptionUtils.CheckArgumentNotNull <Uri>(payloadUri, "payloadUri"); if ((this.contentIdCache != null) && !payloadUri.IsAbsoluteUri) { string str = UriUtilsCommon.UriToString(payloadUri); if ((str.Length > 0) && (str[0] == '$')) { string str2; int index = str.IndexOf('/', 1); if (index > 0) { str2 = str.Substring(1, index - 1); } else { str2 = str.Substring(1); } if (this.contentIdCache.Contains(str2)) { return(payloadUri); } } } if (this.batchMessageUrlResolver != null) { return(this.batchMessageUrlResolver.ResolveUrl(baseUri, payloadUri)); } return(null); }
/// <summary>Creates a URI suitable for host-agnostic comparison purposes.</summary> /// <param name="uri">URI to compare.</param> /// <returns>URI suitable for comparison.</returns> private static Uri CreateBaseComparableUri(Uri uri) { Debug.Assert(uri != null, "uri != null"); uri = new Uri(UriUtilsCommon.UriToString(uri).ToUpper(CultureInfo.InvariantCulture), UriKind.RelativeOrAbsolute); UriBuilder builder = new UriBuilder(uri); builder.Host = "h"; builder.Port = 80; builder.Scheme = "http"; return(builder.Uri); }
/// <summary> /// Writes the headers, (optional) Content-ID and the request line /// </summary> /// <param name="writer">Writer to write to.</param> /// <param name="httpMethod">The Http method to be used for this request operation.</param> /// <param name="uri">The Uri to be used for this request operation.</param> internal static void WriteRequestPreamble(TextWriter writer, string httpMethod, Uri uri) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(writer != null, "writer != null"); Debug.Assert(uri != null, "uri != null"); Debug.Assert(uri.IsAbsoluteUri || UriUtilsCommon.UriToString(uri).StartsWith("$", StringComparison.Ordinal), "uri.IsAbsoluteUri || uri.OriginalString.StartsWith(\"$\")"); // write the headers writer.WriteLine("{0}: {1}", ODataConstants.ContentTypeHeader, MimeConstants.MimeApplicationHttp); writer.WriteLine("{0}: {1}", ODataConstants.ContentTransferEncoding, ODataConstants.BatchContentTransferEncoding); // write separator line between headers and the request line writer.WriteLine(); writer.WriteLine("{0} {1} {2}", httpMethod, UriUtilsCommon.UriToString(uri), ODataConstants.HttpVersionInBatching); }
/// <summary> /// Method to implement a custom URL resolution scheme. /// This method returns null if not custom resolution is desired. /// If the method returns a non-null URL that value will be used without further validation. /// </summary> /// <param name="baseUri">The (optional) base URI to use for the resolution.</param> /// <param name="payloadUri">The URI read from the payload.</param> /// <returns> /// A <see cref="Uri"/> instance that reflects the custom resolution of the method arguments /// into a URL or null if no custom resolution is desired; in that case the default resolution is used. /// </returns> Uri IODataUrlResolver.ResolveUrl(Uri baseUri, Uri payloadUri) { DebugUtils.CheckNoExternalCallers(); ExceptionUtils.CheckArgumentNotNull(payloadUri, "payloadUri"); if (this.contentIdCache != null && !payloadUri.IsAbsoluteUri) { // On relative URIs none of the properties except for OriginalString, IsAbsoluteUri and UserEscaped are allowed string originalString = UriUtilsCommon.UriToString(payloadUri); Debug.Assert(originalString != null, "Original strings cannot be null in System.Uri."); if (originalString.Length > 0 && originalString[0] == '$') { // if the original strings starts with '$' find the first '/' and see whether // the characters before it are recognized as content ID token string tokenString; int ix = originalString.IndexOf('/', 1); if (ix > 0) { tokenString = originalString.Substring(1, ix - 1); } else { tokenString = originalString.Substring(1); } if (this.contentIdCache.Contains(tokenString)) { // We found a valid content ID cross reference; return the payload URI unchanged. return(payloadUri); } } } if (this.batchMessageUrlResolver != null) { // If we have a resolver from the batch message use it as the fallback. return(this.batchMessageUrlResolver.ResolveUrl(baseUri, payloadUri)); } // Otherwise return null to use the default URL resolution instead. return(null); }
internal static IEdmType ValidateNavigationLink(ODataNavigationLink navigationLink, IEdmEntityType declaringEntityType, ODataPayloadKind?expandedPayloadKind) { if (string.IsNullOrEmpty(navigationLink.Name)) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_LinkMustSpecifyName); } bool flag = ((ODataPayloadKind)expandedPayloadKind) == ODataPayloadKind.EntityReferenceLink; bool flag2 = ((ODataPayloadKind)expandedPayloadKind) == ODataPayloadKind.Feed; Func <object, string> func = null; if ((!flag && navigationLink.IsCollection.HasValue) && (expandedPayloadKind.HasValue && (flag2 != navigationLink.IsCollection.Value))) { func = (((ODataPayloadKind)expandedPayloadKind.Value) == ODataPayloadKind.Feed) ? new Func <object, string>(Microsoft.Data.OData.Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedContent) : new Func <object, string>(Microsoft.Data.OData.Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryContent); } IEdmType definition = null; if (declaringEntityType != null) { definition = ValidateNavigationPropertyDefined(navigationLink.Name, declaringEntityType).Type.Definition; bool flag3 = definition.TypeKind == EdmTypeKind.Collection; if (navigationLink.IsCollection.HasValue) { bool flag4 = flag3; if ((flag4 != navigationLink.IsCollection) && ((navigationLink.IsCollection != false) || !flag)) { func = flag3 ? new Func <object, string>(Microsoft.Data.OData.Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedMetadata) : new Func <object, string>(Microsoft.Data.OData.Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryMetadata); } } if ((!flag && expandedPayloadKind.HasValue) && (flag3 != flag2)) { func = flag3 ? new Func <object, string>(Microsoft.Data.OData.Strings.WriterValidationUtils_ExpandedLinkWithEntryPayloadAndFeedMetadata) : new Func <object, string>(Microsoft.Data.OData.Strings.WriterValidationUtils_ExpandedLinkWithFeedPayloadAndEntryMetadata); } } if (func != null) { string arg = (navigationLink.Url == null) ? "null" : UriUtilsCommon.UriToString(navigationLink.Url); throw new ODataException(func(arg)); } return(definition); }
/// <summary> /// Creates the URI for a batch request operation. /// </summary> /// <param name="uri">The uri to process.</param> /// <param name="baseUri">The base Uri to use.</param> /// <param name="urlResolver">An optional custom URL resolver to resolve URLs for writing them into the payload.</param> /// <returns>An URI to be used in the request line of a batch request operation. It uses the <paramref name="urlResolver"/> /// first and falls back to the defaullt URI building schema if the no URL resolver is specified or the URL resolver /// returns null. In the default scheme, the method either returns the specified <paramref name="uri"/> if it was absolute, /// or it's combination with the <paramref name="baseUri"/> if it was relative.</returns> /// <remarks> /// This method will fail if no custom resolution is implemented and the specified <paramref name="uri"/> is /// relative and there's no base URI available. /// </remarks> internal static Uri CreateOperationRequestUri(Uri uri, Uri baseUri, IODataUrlResolver urlResolver) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(uri != null, "uri != null"); Uri resultUri; if (urlResolver != null) { // The resolver returns 'null' if no custom resolution is desired. resultUri = urlResolver.ResolveUrl(baseUri, uri); if (resultUri != null) { return(resultUri); } } if (uri.IsAbsoluteUri) { resultUri = uri; } else { if (baseUri == null) { string errorMessage = UriUtilsCommon.UriToString(uri).StartsWith("$", StringComparison.Ordinal) ? Strings.ODataBatchUtils_RelativeUriStartingWithDollarUsedWithoutBaseUriSpecified(UriUtilsCommon.UriToString(uri)) : Strings.ODataBatchUtils_RelativeUriUsedWithoutBaseUriSpecified(UriUtilsCommon.UriToString(uri)); throw new ODataException(errorMessage); } resultUri = UriUtils.UriToAbsoluteUri(baseUri, uri); } return(resultUri); }
internal static IEdmType ValidateNavigationLink(ODataNavigationLink navigationLink, IEdmEntityType declaringEntityType, ODataPayloadKind?expandedPayloadKind) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(navigationLink != null, "navigationLink != null"); Debug.Assert( !expandedPayloadKind.HasValue || expandedPayloadKind.Value == ODataPayloadKind.EntityReferenceLink || expandedPayloadKind.Value == ODataPayloadKind.Entry || expandedPayloadKind.Value == ODataPayloadKind.Feed, "If an expanded payload kind is specified it must be entry, feed or entity reference link."); // Navigation link must have a non-empty name if (string.IsNullOrEmpty(navigationLink.Name)) { throw new ODataException(Strings.ValidationUtils_LinkMustSpecifyName); } // If we write an entity reference link, don't validate the multiplicity of the IsCollection // property if it is 'false' (since we allow writing a singleton navigation link for // a colleciton navigation property in requests) nor the consistency of payload kind and metadata // (which is done separately in ODataWriterCore.CheckForNavigationLinkWithContent). bool isEntityReferenceLinkPayload = expandedPayloadKind == ODataPayloadKind.EntityReferenceLink; // true only if the expandedPayloadKind has a value and the value is 'Feed' bool isFeedPayload = expandedPayloadKind == ODataPayloadKind.Feed; // Make sure the IsCollection property agrees with the payload kind for entry and feed payloads Func <object, string> errorTemplate = null; if (!isEntityReferenceLinkPayload && navigationLink.IsCollection.HasValue && expandedPayloadKind.HasValue) { // For feed/entry make sure the IsCollection property is set correctly. if (isFeedPayload != navigationLink.IsCollection.Value) { errorTemplate = expandedPayloadKind.Value == ODataPayloadKind.Feed ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedContent : Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryContent; } } IEdmType navigationPropertyType = null; if (declaringEntityType != null) { IEdmProperty navigationProperty = WriterValidationUtils.ValidateNavigationPropertyDefined(navigationLink.Name, declaringEntityType); Debug.Assert(navigationProperty != null, "If we have a declaring type we expect a non-null navigation property since open nav props are not allowed."); navigationPropertyType = navigationProperty.Type.Definition; bool isCollectionType = navigationPropertyType.TypeKind == EdmTypeKind.Collection; // Make sure the IsCollection property agrees with the metadata type for entry and feed payloads if (navigationLink.IsCollection.HasValue && isCollectionType != navigationLink.IsCollection) { // Ignore the case where IsCollection is 'false' and we are writing an entity reference link // (see comment above) if (!(navigationLink.IsCollection == false && isEntityReferenceLinkPayload)) { errorTemplate = isCollectionType ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedMetadata : Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryMetadata; } } // Make sure that the payload kind agrees with the metadata. // For entity reference links we check separately in ODataWriterCore.CheckForNavigationLinkWithContent. if (!isEntityReferenceLinkPayload && expandedPayloadKind.HasValue && isCollectionType != isFeedPayload) { errorTemplate = isCollectionType ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkWithEntryPayloadAndFeedMetadata : Strings.WriterValidationUtils_ExpandedLinkWithFeedPayloadAndEntryMetadata; } } if (errorTemplate != null) { string uri = navigationLink.Url == null ? "null" : UriUtilsCommon.UriToString(navigationLink.Url); throw new ODataException(errorTemplate(uri)); } return(navigationPropertyType); }
/// <summary> /// Validates that message writer settings are correct. /// </summary> /// <param name="messageWriterSettings">The message writer settings to validate.</param> internal static void ValidateMessageWriterSettings(ODataMessageWriterSettings messageWriterSettings) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null"); if (messageWriterSettings.BaseUri != null && !messageWriterSettings.BaseUri.IsAbsoluteUri) { throw new ODataException(Strings.WriterValidationUtils_MessageWriterSettingsBaseUriMustBeNullOrAbsolute(UriUtilsCommon.UriToString(messageWriterSettings.BaseUri))); } }
internal static void ValidateMessageReaderSettings(ODataMessageReaderSettings messageReaderSettings, bool readingResponse) { if ((messageReaderSettings.BaseUri != null) && !messageReaderSettings.BaseUri.IsAbsoluteUri) { throw new ODataException(Microsoft.Data.OData.Strings.ReaderValidationUtils_MessageReaderSettingsBaseUriMustBeNullOrAbsolute(UriUtilsCommon.UriToString(messageReaderSettings.BaseUri))); } if (!readingResponse && (messageReaderSettings.UndeclaredPropertyBehaviorKinds != ODataUndeclaredPropertyBehaviorKinds.None)) { throw new ODataException(Microsoft.Data.OData.Strings.ReaderValidationUtils_UndeclaredPropertyBehaviorKindSpecifiedOnRequest); } if (!string.IsNullOrEmpty(messageReaderSettings.ReaderBehavior.ODataTypeScheme) && !string.Equals(messageReaderSettings.ReaderBehavior.ODataTypeScheme, "http://schemas.microsoft.com/ado/2007/08/dataservices/scheme")) { ODataVersionChecker.CheckCustomTypeScheme(messageReaderSettings.MaxProtocolVersion); } if (!string.IsNullOrEmpty(messageReaderSettings.ReaderBehavior.ODataNamespace) && !string.Equals(messageReaderSettings.ReaderBehavior.ODataNamespace, "http://schemas.microsoft.com/ado/2007/08/dataservices")) { ODataVersionChecker.CheckCustomDataNamespace(messageReaderSettings.MaxProtocolVersion); } }
internal static Uri CreateOperationRequestUri(Uri uri, Uri baseUri, IODataUrlResolver urlResolver) { if (urlResolver != null) { Uri uri2 = urlResolver.ResolveUrl(baseUri, uri); if (uri2 != null) { return(uri2); } } if (uri.IsAbsoluteUri) { return(uri); } if (baseUri == null) { string message = uri.OriginalString.StartsWith("$", StringComparison.Ordinal) ? Strings.ODataBatchUtils_RelativeUriStartingWithDollarUsedWithoutBaseUriSpecified(UriUtilsCommon.UriToString(uri)) : Strings.ODataBatchUtils_RelativeUriUsedWithoutBaseUriSpecified(UriUtilsCommon.UriToString(uri)); throw new ODataException(message); } return(UriUtils.UriToAbsoluteUri(baseUri, uri)); }
internal static void ValidateMessageWriterSettings(ODataMessageWriterSettings messageWriterSettings) { if ((messageWriterSettings.BaseUri != null) && !messageWriterSettings.BaseUri.IsAbsoluteUri) { throw new ODataException(Microsoft.Data.OData.Strings.WriterValidationUtils_MessageWriterSettingsBaseUriMustBeNullOrAbsolute(UriUtilsCommon.UriToString(messageWriterSettings.BaseUri))); } }
/// <summary> /// Initializes a new instance of <see cref="ODataMetadataDocumentUri"/>. /// </summary> /// <param name="baseUri">The base uri to the metadata document.</param> internal ODataMetadataDocumentUri(Uri baseUri) { DebugUtils.CheckNoExternalCallers(); ExceptionUtils.CheckArgumentNotNull(baseUri, "baseUri"); if (!baseUri.IsAbsoluteUri) { throw new ODataException(Strings.WriterValidationUtils_MessageWriterSettingsMetadataDocumentUriMustBeNullOrAbsolute(UriUtilsCommon.UriToString(baseUri))); } this.baseUri = baseUri; }
/// <summary> /// Sets the metadata builder for this operation. /// </summary> /// <param name="builder">The metadata builder used to compute values from model annotations.</param> /// <param name="metadataDocumentUri">The metadata document Uri.</param> internal void SetMetadataBuilder(ODataEntityMetadataBuilder builder, Uri metadataDocumentUri) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(metadataDocumentUri != null, "metadataDocumentUri != null"); Debug.Assert(metadataDocumentUri.IsAbsoluteUri, "metadataDocumentUri.IsAbsoluteUri"); ODataJsonLightValidationUtils.ValidateOperation(metadataDocumentUri, this); this.metadataBuilder = builder; this.operationFullName = ODataJsonLightUtils.GetFullyQualifiedFunctionImportName(metadataDocumentUri, UriUtilsCommon.UriToString(this.Metadata), out this.bindingParameterTypeName); this.computedTitle = null; this.computedTarget = null; }
/// <summary> /// Validates that message writer settings are correct. /// </summary> /// <param name="messageWriterSettings">The message writer settings to validate.</param> /// <param name="writingResponse">True if we are writing a response.</param> internal static void ValidateMessageWriterSettings(ODataMessageWriterSettings messageWriterSettings, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null"); if (messageWriterSettings.BaseUri != null && !messageWriterSettings.BaseUri.IsAbsoluteUri) { throw new ODataException(Strings.WriterValidationUtils_MessageWriterSettingsBaseUriMustBeNullOrAbsolute(UriUtilsCommon.UriToString(messageWriterSettings.BaseUri))); } if (messageWriterSettings.HasJsonPaddingFunction() && !writingResponse) { throw new ODataException(Strings.WriterValidationUtils_MessageWriterSettingsJsonPaddingOnRequestMessage); } }