/// <summary> /// Generates an arbitrary top load payload based on the maximum version supplied. /// </summary> /// <param name="random">Random generator for generating arbitrary payloads</param> /// <param name="model">The model to add any new types to</param> /// <param name="version">Maximum version for generated payloads.</param> /// <returns>A top level payload.</returns> public static ODataPayloadElement GetRandomPayload(IRandomNumberGenerator random, EdmModel model, ODataVersion version = ODataVersion.V4) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(model, "model"); Func<ODataPayloadElement>[] payloadCalls = new Func<ODataPayloadElement>[] { () => { return GetComplexInstanceCollection(random, model, version); }, () => { return GetComplexProperty(random, model, version); }, () => { return GetDeferredLink(); }, () => { return GetLinkCollection(); }, () => { return GetEntityInstance(random, model, version); }, () => { return GetEntitySetInstance(random, model); }, () => { return GetODataErrorPayload(random); }, () => { return GetPrimitiveCollection(random); }, () => { return GetPrimitiveProperty(random, model); }, () => { return GetPrimitiveValue(random, model); }, }; payloadCalls.Concat(new Func<ODataPayloadElement>[] { () => { return GetComplexMultiValueProperty(random, model, version); }, () => { return GetPrimitiveMultiValueProperty(random); }, }); var payloadCall = random.ChooseFrom(payloadCalls); return payloadCall(); }
public static string ConvertToUriLiteral(object value, ODataVersion version, IEdmModel model) { if (value == null) { value = new ODataUriNullValue(); } if (model == null) { model = EdmCoreModel.Instance; } ODataUriNullValue nullValue = value as ODataUriNullValue; if (nullValue != null) { return ODataUriConversionUtils.ConvertToUriNullValue(nullValue, model); } ODataCollectionValue collectionValue = value as ODataCollectionValue; if (collectionValue != null) { return ODataUriConversionUtils.ConvertToUriCollectionLiteral(collectionValue, model, version); } ODataComplexValue complexValue = value as ODataComplexValue; if (complexValue != null) { return ODataUriConversionUtils.ConvertToUriComplexLiteral(complexValue, model, version); } return ODataUriConversionUtils.ConvertToUriPrimitiveLiteral(value, version); }
/// <summary> /// Writes the json object value to the <paramref name="jsonWriter"/>. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="jsonObjectValue">Writes the given json object value to the underlying json writer.</param> /// <param name="typeName">Type name of the json object to write. If type name is null, no type name is written.</param> /// <param name="odataVersion">The OData protocol version to be used for writing payloads.</param> internal static void WriteJsonObjectValue(this JsonWriter jsonWriter, IDictionary<string, object> jsonObjectValue, string typeName, ODataVersion odataVersion) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(jsonObjectValue != null, "jsonObjectValue != null"); jsonWriter.StartObjectScope(); if (typeName != null) { Debug.Assert(!jsonObjectValue.ContainsKey(JsonConstants.ODataMetadataName), "__metadata should not be present in jsonObjectValue"); jsonWriter.WriteName(JsonConstants.ODataMetadataName); jsonWriter.StartObjectScope(); jsonWriter.WriteName(JsonConstants.ODataMetadataTypeName); jsonWriter.WriteValue(typeName); jsonWriter.EndObjectScope(); } foreach (KeyValuePair<string, object> property in jsonObjectValue) { jsonWriter.WriteName(property.Key); jsonWriter.WriteJsonValue(property.Value, odataVersion); } jsonWriter.EndObjectScope(); }
public static object ConvertFromUriLiteral(string value, ODataVersion version, IEdmModel model, IEdmTypeReference typeReference) { Exception exception; ExpressionToken token; ExceptionUtils.CheckArgumentNotNull<string>(value, "value"); if ((typeReference != null) && (model == null)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataUriUtils_ConvertFromUriLiteralTypeRefWithoutModel); } if (model == null) { model = EdmCoreModel.Instance; } ExpressionLexer lexer = new ExpressionLexer(value, false); if (!lexer.TryPeekNextToken(out token, out exception)) { return ODataUriConversionUtils.ConvertFromComplexOrCollectionValue(value, version, model, typeReference); } object primitiveValue = lexer.ReadLiteralToken(); if (typeReference != null) { primitiveValue = ODataUriConversionUtils.VerifyAndCoerceUriPrimitiveLiteral(primitiveValue, model, typeReference, version); } if (primitiveValue is ISpatial) { ODataVersionChecker.CheckSpatialValue(version); } return primitiveValue; }
internal static void CheckNextLink(ODataVersion version) { if (version < ODataVersion.V2) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_NextLinkNotSupported(ODataUtils.ODataVersionToString(version))); } }
/// <summary> /// Converts an item from the data store into an ODataEntry. /// </summary> /// <param name="element">The item to convert.</param> /// <param name="entitySet">The entity set that the item belongs to.</param> /// <param name="targetVersion">The OData version this segment is targeting.</param> /// <returns>The converted ODataEntry.</returns> public static ODataEntry ConvertToODataEntry(object element, IEdmEntitySet entitySet, ODataVersion targetVersion) { IEdmEntityType entityType = entitySet.EntityType(); Uri entryUri = BuildEntryUri(element, entitySet, targetVersion); var entry = new ODataEntry { // writes out the edit link including the service base uri , e.g.: http://<serviceBase>/Customers('ALFKI') EditLink = entryUri, // writes out the self link including the service base uri , e.g.: http://<serviceBase>/Customers('ALFKI') ReadLink = entryUri, // we use the EditLink as the Id for this entity to maintain convention, Id = entryUri, // writes out the <category term='Customer'/> element TypeName = element.GetType().Namespace + "." + entityType.Name, Properties = entityType.StructuralProperties().Select(p => ConvertToODataProperty(element, p.Name)), }; return entry; }
internal void WriteJson(object instance, JsonWriter jsonWriter, string typeName, ODataVersion odataVersion) { IPrimitiveTypeConverter converter; Type type = instance.GetType(); this.TryGetConverter(type, out converter); converter.WriteJson(instance, jsonWriter, typeName, odataVersion); }
internal static IEdmTypeReference ResolveAndValidateNonPrimitiveTargetType(EdmTypeKind expectedTypeKind, IEdmTypeReference expectedTypeReference, EdmTypeKind payloadTypeKind, IEdmType payloadType, string payloadTypeName, IEdmModel model, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, out SerializationTypeNameAnnotation serializationTypeNameAnnotation) { bool flag = (messageReaderSettings.ReaderBehavior.TypeResolver != null) && (payloadType != null); if (!flag) { ValidateTypeSupported(expectedTypeReference, version); if (model.IsUserModel() && ((expectedTypeReference == null) || !messageReaderSettings.DisableStrictMetadataValidation)) { VerifyPayloadTypeDefined(payloadTypeName, payloadType); } } else { ValidateTypeSupported((payloadType == null) ? null : payloadType.ToTypeReference(true), version); } if ((payloadTypeKind != EdmTypeKind.None) && (!messageReaderSettings.DisableStrictMetadataValidation || (expectedTypeReference == null))) { ValidationUtils.ValidateTypeKind(payloadTypeKind, expectedTypeKind, payloadTypeName); } serializationTypeNameAnnotation = null; if (!model.IsUserModel()) { return null; } if ((expectedTypeReference == null) || flag) { return ResolveAndValidateTargetTypeWithNoExpectedType(expectedTypeKind, payloadType, payloadTypeName, out serializationTypeNameAnnotation); } if (messageReaderSettings.DisableStrictMetadataValidation) { return ResolveAndValidateTargetTypeStrictValidationDisabled(expectedTypeKind, expectedTypeReference, payloadType, payloadTypeName, out serializationTypeNameAnnotation); } return ResolveAndValidateTargetTypeStrictValidationEnabled(expectedTypeKind, expectedTypeReference, payloadType, payloadTypeName, out serializationTypeNameAnnotation); }
internal static void CheckCollectionValueProperties(ODataVersion version, string propertyName) { if (version < ODataVersion.V3) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_CollectionPropertiesNotSupported(propertyName, ODataUtils.ODataVersionToString(version))); } }
/// <summary> /// Computes the expected exception for this test case. /// </summary> /// <param name="behaviorKind">The <see cref="TestODataBehaviorKind"/> used by this test variation.</param> /// <param name="version">The <see cref="ODataVersion"/> used by this test variation.</param> /// <param name="ignoredOnServer">true if the payload value is ignored on the server; otherwise false.</param> /// <returns>The expected exception for a test variation using the specified parameter values; null if no exception is expected.</returns> public ExpectedException ComputeExpectedException(TestODataBehaviorKind behaviorKind, ODataVersion version, bool ignoredOnServer) { bool settingsBaseIsNullOrRelative = this.SettingsBaseUri == null || !(new Uri(this.SettingsBaseUri, UriKind.RelativeOrAbsolute).IsAbsoluteUri); bool xmlBaseIsNullOrRelative = this.XmlBaseUri == null || !(new Uri(this.XmlBaseUri, UriKind.RelativeOrAbsolute).IsAbsoluteUri); bool ignoreXmlBase = false; // If both the settings base URI and an xml:base are relative we will fail when we detect the xml:base. if (settingsBaseIsNullOrRelative && xmlBaseIsNullOrRelative && !ignoreXmlBase) { string relativeBase = this.XmlBaseUri == null ? string.Empty : this.XmlBaseUri; return ODataExpectedExceptions.ODataException("ODataAtomDeserializer_RelativeUriUsedWithoutBaseUriSpecified", relativeBase); } // Special rules for WCF DS server behavior. if (behaviorKind == TestODataBehaviorKind.WcfDataServicesServer) { // If the payload is ignored on the server, we expect no exception. if (ignoredOnServer) { return null; } } return null; }
internal static void CheckAssociationLinks(ODataVersion version) { if (version < ODataVersion.V3) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_AssociationLinksNotSupported(ODataUtils.ODataVersionToString(version))); } }
/// <summary> /// Constructor. /// </summary> /// <param name="format">The format used for the test.</param> /// <param name="version">The OData protocol version to be used for the payload.</param> /// <param name="request">True if the test is reading a request. Otherwise false if it's reading a response.</param> public TestConfiguration(ODataFormat format, ODataVersion version, bool request, TestODataBehaviorKind behaviorKind) { this.Format = format; this.Version = version; this.IsRequest = request; this.RunBehaviorKind = behaviorKind; }
internal static void CheckParameterPayload(ODataVersion version) { if (version < ODataVersion.V3) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_ParameterPayloadNotSupported(ODataUtils.ODataVersionToString(version))); } }
internal static void CheckSpatialValue(ODataVersion version) { if (version < ODataVersion.V3) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_GeographyAndGeometryNotSupported(ODataUtils.ODataVersionToString(version))); } }
internal static void CheckCollectionValue(ODataVersion version) { if (version < ODataVersion.V3) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_CollectionNotSupported(ODataUtils.ODataVersionToString(version))); } }
internal static void CheckCustomTypeScheme(ODataVersion version) { if (version > ODataVersion.V2) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_PropertyNotSupportedForODataVersionGreaterThanX("TypeScheme", ODataUtils.ODataVersionToString(ODataVersion.V2))); } }
/// <summary> /// Writes an OData entry. /// </summary> /// <param name="writer">The ODataWriter that will write the entry.</param> /// <param name="element">The item from the data store to write.</param> /// <param name="navigationSource">The navigation source in the model that the entry belongs to.</param> /// <param name="model">The data store model.</param> /// <param name="targetVersion">The OData version this segment is targeting.</param> /// <param name="selectExpandClause">The SelectExpandClause.</param> public static void WriteEntry(ODataWriter writer, object element, IEdmNavigationSource entitySource, ODataVersion targetVersion, SelectExpandClause selectExpandClause, Dictionary<string, string> incomingHeaders = null) { var entry = ODataObjectModelConverter.ConvertToODataEntry(element, entitySource, targetVersion); entry.ETag = Utility.GetETagValue(element); if (selectExpandClause != null && selectExpandClause.SelectedItems.OfType<PathSelectItem>().Any()) { ExpandSelectItemHandler selectItemHandler = new ExpandSelectItemHandler(entry); foreach (var item in selectExpandClause.SelectedItems.OfType<PathSelectItem>()) { item.HandleWith(selectItemHandler); } entry = selectItemHandler.ProjectedEntry; } CustomizeEntry(incomingHeaders, entry); writer.WriteStart(entry); // gets all of the expandedItems, including ExpandedRefernceSelectItem and ExpandedNavigationItem var expandedItems = selectExpandClause == null ? null : selectExpandClause.SelectedItems.OfType<ExpandedReferenceSelectItem>(); WriteNavigationLinks(writer, element, entry.ReadLink, entitySource, targetVersion, expandedItems); writer.WriteEnd(); }
/// <summary> /// Sets the configuration limit to require minimum payload version. /// </summary> /// <param name="version">The minimum payload version required.</param> public void RaiseMinPayloadVersion(ODataVersion version) { if (this.minPayloadVersion < version) { this.minPayloadVersion = version; } }
/// <summary> /// Initializes a new instance of the <see cref="ODataMediaTypeFormatter"/> class. /// </summary> /// <param name="deserializerProvider">The <see cref="ODataDeserializerProvider"/> to use.</param> /// <param name="serializerProvider">The <see cref="ODataSerializerProvider"/> to use.</param> /// <param name="payloadKinds">The kind of payloads this formatter supports.</param> public ODataMediaTypeFormatter(ODataDeserializerProvider deserializerProvider, ODataSerializerProvider serializerProvider, IEnumerable<ODataPayloadKind> payloadKinds) { if (deserializerProvider == null) { throw Error.ArgumentNull("deserializerProvider"); } if (serializerProvider == null) { throw Error.ArgumentNull("serializerProvider"); } if (payloadKinds == null) { throw Error.ArgumentNull("payloadKinds"); } _deserializerProvider = deserializerProvider; _serializerProvider = serializerProvider; _payloadKinds = payloadKinds; // Maxing out the received message size as we depend on the hosting layer to enforce this limit. MessageReaderQuotas = new ODataMessageQuotas { MaxReceivedMessageSize = Int64.MaxValue }; MessageWriterQuotas = new ODataMessageQuotas { MaxReceivedMessageSize = Int64.MaxValue }; _version = DefaultODataVersion; }
/// <summary> /// Generates extra operations to go into a request changeset /// </summary> /// <param name="random">For generating the payloads to go in the extra operations</param> /// <param name="requestManager">For building the operations</param> /// <param name="model">To add any new types to.</param> /// <param name="baseUri">Base uri for the extra operations.</param> /// <param name="version">Maximum version for </param> /// <returns>An array of extra request operations.</returns> public static IHttpRequest[] ExtraRequestChangesetOperations( IRandomNumberGenerator random, IODataRequestManager requestManager, EdmModel model, ODataUri baseUri, ODataVersion version = ODataVersion.V4) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); ExceptionUtilities.CheckArgumentNotNull(baseUri, "baseUri"); var headers = new Dictionary<string, string> { { "RequestHeader", "RequestHeaderValue" } }; string mergeContentType = HttpUtilities.BuildContentType(MimeTypes.ApplicationXml, Encoding.UTF8.WebName, null); List<IHttpRequest> requests = new List<IHttpRequest>(); ODataRequest request = null; for (int i = 0; i < 4; i++) { request = requestManager.BuildRequest(baseUri, HttpVerb.Post, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Put, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Patch, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Delete, headers); requests.Add(request); } return requests.ToArray(); }
/// <summary> /// Constructor. /// </summary> /// <param name="format">The format used for the test.</param> /// <param name="messageReaderSettings">The message reader settings used for the test.</param> /// <param name="readerRequest">True if the test is reading a request. Otherwise false if it's reading a response.</param> /// <param name="synchronous">True if the test should be ran using synchronous API. Otherwise false if it should be ran using asynchronous APIs.</param> /// <param name="version">The OData protocol version to be used for reading the payload.</param> public ReaderTestConfiguration(ODataFormat format, ODataMessageReaderSettings messageReaderSettings, bool IsRequest, bool synchronous,ODataVersion version = ODataVersion.V4) :base(format, version, IsRequest, TestODataBehaviorKind.Default) { Debug.Assert(messageReaderSettings != null, "readerSettings != null"); this.MessageReaderSettings = messageReaderSettings; this.Synchronous = synchronous; }
/// <summary> /// Reads the OData-Version header from the <paramref name="message"/> and parses it. /// If no OData-Version header is found it sets the default version to be used for reading. /// </summary> /// <param name="message">The message to get the OData-Version version header from.</param> /// <param name="defaultVersion">The default version to use if the header was not specified.</param> /// <returns> /// The <see cref="ODataVersion"/> retrieved from the OData-Version header of the message. /// The default version if none is specified in the header. /// </returns> public static ODataVersion GetODataVersion(this IODataRequestMessage message, ODataVersion defaultVersion) { // translation from IODataResponseMessage to ODataMessage to pass into GetODataVersion. // we retain all of the data we need from the message, with a few extra data that aren't used in. // GetODataVersion. Not ideal, but it works. ODataMessage odataMessage = new ODataRequestMessage(message, false /*writing*/, false/*disableMessageStreamDisposal*/, Int64.MaxValue /*maxMessageSize*/); return ODataUtilsInternal.GetODataVersion(odataMessage, defaultVersion); }
//public void GetResponse(string uri, string format, ODataVersion version, ODataVersion maxVersion, IEdmModel model, string fileName) //{ // HTTPClientRequestMessage message = new HTTPClientRequestMessage(uri); // message.SetHeader("Accept", format); // message.SetHeader("DataServiceVersion", version.ToHeaderValue()); // message.SetHeader("MaxDataServiceVersion", maxVersion.ToHeaderValue()); // string filePath = @".\out\" + fileName + ".txt"; // using (StreamWriter outputWriter = new StreamWriter(filePath)) // { // this.writer = new IndentedTextWriter(outputWriter, " "); // using (ODataMessageReader messageReader = new ODataMessageReader(message.GetResponse(), new ODataMessageReaderSettings(), model)) // { // ODataReader reader = messageReader.CreateODataFeedReader(); // this.ReadAndOutputEntryOrFeed(reader); // } // } //} public ODataMessageReader GetResponse(string uri, string format, ODataVersion version, ODataVersion maxVersion, IEdmModel model) { HTTPClientRequestMessage message = new HTTPClientRequestMessage(uri); message.SetHeader("Accept", format); message.SetHeader("DataServiceVersion", version.ToHeaderValue()); message.SetHeader("MaxDataServiceVersion", maxVersion.ToHeaderValue()); return new ODataMessageReader(message.GetResponse(), new ODataMessageReaderSettings(), model); }
internal static void CheckEntityPropertyMapping(ODataVersion version, IEdmEntityType entityType, IEdmModel model) { ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType); if ((epmCache != null) && (version < epmCache.EpmTargetTree.MinimumODataProtocolVersion)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_EpmVersionNotSupported(entityType.ODataFullName(), ODataUtils.ODataVersionToString(epmCache.EpmTargetTree.MinimumODataProtocolVersion), ODataUtils.ODataVersionToString(version))); } }
/// <summary> /// Constructor. /// </summary> /// <param name="version">The version of the OData protocol to use.</param> /// <param name="metadataProvider">The metadata provider to use.</param> /// <param name="synchronous">True if the writer is created for synchronous operation; false for asynchronous.</param> protected ODataCollectionWriterCore(ODataVersion version, DataServiceMetadataProviderWrapper metadataProvider, bool synchronous) { DebugUtils.CheckNoExternalCallers(); this.version = version; this.metadataProvider = metadataProvider; this.synchronous = synchronous; this.scopes.Push(new Scope(CollectionWriterState.Start, null)); }
private static void WriteJsonArrayValue(this JsonWriter jsonWriter, IEnumerable arrayValue, ODataVersion odataVersion) { jsonWriter.StartArrayScope(); foreach (object obj2 in arrayValue) { jsonWriter.WriteJsonValue(obj2, odataVersion); } jsonWriter.EndArrayScope(); }
internal static ODataVersion GetDataServiceVersion(ODataMessage message, ODataVersion defaultVersion) { string header = message.GetHeader("DataServiceVersion"); if (!string.IsNullOrEmpty(header)) { return ODataUtils.StringToODataVersion(header); } return defaultVersion; }
/// <summary> /// Check whether the named streams feature is supported in the specified version. /// </summary> /// <param name="version">The version to check.</param> internal static void CheckNamedStreams(ODataVersion version) { DebugUtils.CheckNoExternalCallers(); if (version < ODataVersion.V3) { throw new ODataException(Strings.ODataVersionChecker_NamedStreamsNotSupported(version.VersionString())); } }
/// <summary> /// Check whether the server paging feature is supported in the specified version. /// </summary> /// <param name="version">The version to check.</param> internal static void CheckServerPaging(ODataVersion version) { DebugUtils.CheckNoExternalCallers(); if (version < ODataVersion.V2) { throw new ODataException(Strings.ODataVersionChecker_ServerPagingNotSupported(version.VersionString())); } }
/// <summary> /// Check whether the inline count feature is supported in the specified version. /// </summary> /// <param name="version">The version to check.</param> /// <param name="propertyName">The name of the property which holds the multivalue.</param> internal static void CheckMultiValueProperties(ODataVersion version, string propertyName) { DebugUtils.CheckNoExternalCallers(); if (version < ODataVersion.V3) { throw new ODataException(Strings.ODataVersionChecker_MultiValuePropertiesNotSupported(propertyName, version.VersionString())); } }
/// <summary> /// Converts a primitive to a string for use in a Url. /// </summary> /// <param name="value">Value to convert.</param> /// <param name="version">OData version to be compliant with.</param> /// <returns>A string representation of <paramref name="value"/> to be added to a Url.</returns> internal static string ConvertToUriPrimitiveLiteral(object value, ODataVersion version) { ExceptionUtils.CheckArgumentNotNull(value, "value"); // TODO: Differences between Astoria and ODL's Uri literals /* This should have the same behavior of Astoria with these differences: * 1) Cannot handle the System.Data.Linq.Binary type * 2) Cannot handle the System.Data.Linq.XElement type * 3) Astoria does not put a 'd' or 'D' on double values */ // for legacy backwards compatibility reasons, use the formatter which does not URL-encode the resulting string. return(LiteralFormatter.ForConstantsWithoutEncoding.Format(value)); }
/// <summary> /// Converts the given <paramref name="value"/> to a corresponding CLR type. Expects the /// <paramref name="value"/> to have already been properly unescaped from an actual Uri. /// </summary> /// <param name="value">Value from a Uri to be converted.</param> /// <param name="version">Version to be compliant with.</param> /// <param name="model">Optional model to perform verification against.</param> /// <param name="typeReference">Optional IEdmTypeReference to perform verification against. /// Callers must provide a <paramref name="model"/> containing this type if it is specified.</param> /// <returns>A CLR object that the <paramref name="value"/> represents or an EnumNode.</returns> public static object ConvertFromUriLiteral(string value, ODataVersion version, IEdmModel model, IEdmTypeReference typeReference) { ExceptionUtils.CheckArgumentNotNull(value, "value"); if (typeReference != null && model == null) { throw new ODataException(ODataErrorStrings.ODataUriUtils_ConvertFromUriLiteralTypeRefWithoutModel); } if (model == null) { model = Microsoft.OData.Edm.EdmCoreModel.Instance; } // Let ExpressionLexer try to get a primitive ExpressionLexer lexer = new ExpressionLexer(value, false /*moveToFirstToken*/, false /*useSemicolonDelimeter*/); Exception error; ExpressionToken token; lexer.TryPeekNextToken(out token, out error); if (token.Kind == ExpressionTokenKind.BracedExpression && typeReference != null && typeReference.IsStructured()) { return(ODataUriConversionUtils.ConvertFromResourceValue(value, model, typeReference)); } if (token.Kind == ExpressionTokenKind.BracketedExpression) { return(ODataUriConversionUtils.ConvertFromCollectionValue(value, model, typeReference)); } QueryNode enumConstNode; if ((token.Kind == ExpressionTokenKind.Identifier) && // then try parsing the entire text as enum value EnumBinder.TryBindIdentifier(lexer.ExpressionText, null, model, out enumConstNode)) { return(((ConstantNode)enumConstNode).Value); } object result = lexer.ReadLiteralToken(); // If we have a typeReference then perform verification and convert if necessary if (typeReference != null) { result = ODataUriConversionUtils.VerifyAndCoerceUriPrimitiveLiteral(result, value, model, typeReference); } return(result); }
/// <summary> /// Verify the rule /// </summary> /// <param name="context">Service context</param> /// <param name="info">out parameter to return violation information when rule fail</param> /// <returns>true if rule passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; // if __metadata.etag property is there, ensure its value equals to ETag header value var entry = JsonParserHelper.GetResponseObject(context); var etag = entry.GetPropertyOfChild("__metadata", "etag"); bool etagInPlace = etag != null; if (etagInPlace) { var etagInHeader = context.ResponseHttpHeaders.GetHeaderValue("ETag").Trim(); var etagLiteral = StringHelper.ToLiteral(etagInHeader); RuleEngine.TestResult result = null; ODataVersion version = JsonParserHelper.GetPayloadODataVersion(entry); switch (version) { case ODataVersion.V1: string schemaV1 = string.Format(EntryCore2009.schemaFormat_v1, etagLiteral); passed = JsonParserHelper.ValidateJson(schemaV1, context.ResponsePayload, out result); break; case ODataVersion.V2: string schemaV2 = string.Format(EntryCore2009.schemaFormat_v2, etagLiteral); passed = JsonParserHelper.ValidateJson(schemaV2, context.ResponsePayload, out result); break; default: passed = false; break; } if (!passed.Value) { info = new ExtensionRuleViolationInfo(this.ErrorMessage, context.Destination, context.ResponsePayload, result != null ? result.LineNumberInError : -1); } } return(passed); }
internal static Task <HttpResponseMessage> CreateODataBatchResponseAsync(this HttpRequestMessage request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas) { Contract.Assert(request != null); ODataVersion odataVersion = ResultHelpers.GetODataResponseVersion(request); IServiceProvider requestContainer = request.GetRequestContainer(); ODataMessageWriterSettings writerSettings = requestContainer.GetRequiredService <ODataMessageWriterSettings>(); writerSettings.Version = odataVersion; writerSettings.MessageQuotas = messageQuotas; HttpHeaderValueCollection <MediaTypeWithQualityHeaderValue> acceptHeaderValues = request.Headers.Accept; MediaTypeHeaderValue responseContentType = null; foreach (MediaTypeWithQualityHeaderValue acceptHeader in acceptHeaderValues.OrderByDescending(h => h.Quality == null ? 1 : h.Quality)) { if (acceptHeader.MediaType.Equals(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeMime, StringComparison.OrdinalIgnoreCase)) { responseContentType = MediaTypeHeaderValue.Parse( String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid())); break; } else if (acceptHeader.MediaType.Equals(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase)) { responseContentType = MediaTypeHeaderValue.Parse(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson); break; } } if (responseContentType == null) { // In absence of accept, if request was JSON then default response to be JSON. // Note that, if responseContentType is not set, then it will default to multipart/mixed // when constructing the BatchContent, so we don't need to handle that case here if (request.Content != null && request.Content.Headers.Any(h => String.Equals(h.Key, ODataBatchHttpRequestMessageExtensions.ContentType, StringComparison.OrdinalIgnoreCase) && h.Value.Any(v => v.IndexOf(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase) > -1))) { responseContentType = MediaTypeHeaderValue.Parse(ODataBatchHttpRequestMessageExtensions.BatchMediaTypeJson); } } HttpResponseMessage response = request.CreateResponse(HttpStatusCode.OK); response.Content = new ODataBatchContent(responses, requestContainer, responseContentType); return(Task.FromResult(response)); }
internal static Task CreateODataBatchResponseAsync(this HttpRequest request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas) { Contract.Assert(request != null); ODataVersion odataVersion = GetODataResponseVersion(request); IServiceProvider requestContainer = request.GetSubServiceProvider(); ODataMessageWriterSettings writerSettings = requestContainer.GetRequiredService <ODataMessageWriterSettings>(); writerSettings.Version = odataVersion; writerSettings.MessageQuotas = messageQuotas; HttpResponse response = request.HttpContext.Response; StringValues acceptHeader = request.Headers["Accept"]; string responseContentType = null; if (StringValues.IsNullOrEmpty(acceptHeader)) { // In absence of accept, if request was JSON then default response to be JSON. // Note that, if responseContentType is not set, then it will default to multipart/mixed // when constructing the BatchContent, so we don't need to handle that case here if (!String.IsNullOrEmpty(request.ContentType) && request.ContentType.IndexOf(BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase) > -1) { responseContentType = BatchMediaTypeJson; } } else if (acceptHeader.Any(h => h.Equals(BatchMediaTypeMime, StringComparison.OrdinalIgnoreCase))) { responseContentType = String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid()); } else if (acceptHeader.Any(h => h.IndexOf(BatchMediaTypeJson, StringComparison.OrdinalIgnoreCase) > -1)) { responseContentType = BatchMediaTypeJson; } response.StatusCode = StatusCodes.Status200OK; ODataBatchContent batchContent = new ODataBatchContent(responses, requestContainer, responseContentType); foreach (var header in batchContent.Headers) { // Copy headers from batch content, overwriting any existing headers. response.Headers[header.Key] = header.Value; } return(batchContent.SerializeToStreamAsync(response.Body)); }
/// <summary> /// Validates an <see cref="ODataFeed"/> to ensure all required information is specified and valid on the WriteEnd call. /// </summary> /// <param name="feed">The feed to validate.</param> /// <param name="writingRequest">Flag indicating whether the feed is written as part of a request or a response.</param> /// <param name="version">The version of the OData protocol used for checking.</param> internal static void ValidateFeedAtEnd(ODataFeed feed, bool writingRequest, ODataVersion version) { Debug.Assert(feed != null, "feed != null"); // Verify next link if (feed.NextPageLink != null) { // Check that NextPageLink is not set for requests if (writingRequest) { throw new ODataException(Strings.WriterValidationUtils_NextPageLinkInRequest); } } // Verify version requirements }
/// <summary> /// Gets Json schema for specific node along the path segment sequence /// </summary> /// <param name="paths">The path segment sequence</param> /// <param name="i">The index of segment under concern</param> /// <param name="version">OData version for which the schema to generate</param> /// <param name="jsCore">The Json schema defintion for the indexed segement</param> /// <param name="flagOfArray">The supplementary collection of flags indicating segment is array or object</param> /// <returns>The Json schema generated for the segments from top till the indexed segment</returns> public static string GetJsonSchema(string[] paths, int i, ODataVersion version, string jsCore, bool[] flagOfArray) { for (int j = i - 1; j >= 0; j--) { if (!flagOfArray[j]) { jsCore = string.Format(JsonSchemaHelper.fmtContainerAsObject, paths[j], jsCore); } else { jsCore = string.Format(JsonSchemaHelper.fmtContainerAsArray, paths[j], jsCore); } } return(WrapObjectWithProperties(jsCore, version)); }
/// <inheritdoc/> public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType) { // call base to validate parameters base.GetPerRequestFormatterInstance(type, request, mediaType); // Adds model information to allow callers to identify the ODataMediaTypeFormatter through the tracing wrapper // This is a workaround until tracing provides information about the wrapped inner formatter if (type == typeof(IEdmModel)) { request.Properties.Add(EdmModelKey, _model); } ODataVersion version = GetResponseODataVersion(request); return(new ODataMediaTypeFormatter(this, version, request)); }
/// <summary> /// Resolves the name of a primitive, complex, entity or collection type to the respective type. Uses the semantics used be readers. /// Thus it can be a bit looser. /// </summary> /// <param name="model">The model to use.</param> /// <param name="expectedType">The expected type for the type name being resolved, or null if none is available.</param> /// <param name="typeName">The name of the type to resolve.</param> /// <param name="readerBehavior">Reader behavior if the caller is a reader, null if no reader behavior is available.</param> /// <param name="version">The version of the payload being read.</param> /// <param name="typeKind">The type kind of the type, if it could be determined. This will be None if we couldn't tell. It might be filled /// even if the method returns null, for example for Collection types with item types which are not recognized.</param> /// <returns>The <see cref="IEdmType"/> representing the type specified by the <paramref name="typeName"/>; /// or null if no such type could be found.</returns> internal static IEdmType ResolveTypeNameForRead( IEdmModel model, IEdmType expectedType, string typeName, ODataReaderBehavior readerBehavior, ODataVersion version, out EdmTypeKind typeKind) { Func <IEdmType, string, IEdmType> customTypeResolver = readerBehavior == null ? null : readerBehavior.TypeResolver; Debug.Assert( customTypeResolver == null || readerBehavior.ApiBehaviorKind == ODataBehaviorKind.WcfDataServicesClient, "Custom type resolver can only be specified in WCF DS Client behavior."); return(ResolveTypeName(model, expectedType, typeName, customTypeResolver, version, out typeKind)); }
/// <summary> /// Returns the string representation used in error message for example for the specified OData version. /// </summary> /// <param name="version">The version to process.</param> /// <returns>The string representation of the version.</returns> public static string ToText(this ODataVersion version) { switch (version) { case ODataVersion.V4: return("4.0"); case ODataVersion.V401: return("4.01"); default: string errorMessage = "Unsupported version '" + version.ToString() + "' found."; Debug.Assert(false, errorMessage); throw new NotSupportedException(errorMessage); } }
/// <summary> /// Returns the DataServiceProtocolVersion representation of the specified OData version. /// </summary> /// <param name="version">The version to process.</param> /// <returns>The DataServiceProtocolVersion value.</returns> public static DataServiceProtocolVersion ToDataServiceProtocolVersion(this ODataVersion version) { switch (version) { case ODataVersion.V4: return(DataServiceProtocolVersion.V4); case ODataVersion.V401: return(DataServiceProtocolVersion.V4_01); default: string errorMessage = "Unsupported version '" + version.ToString() + "' found."; Debug.Assert(false, errorMessage); throw new NotSupportedException(errorMessage); } }
/// <summary> /// Initializes a new instance of the <see cref="ODataBatchContent"/> class. /// </summary> /// <param name="responses">The batch responses.</param> /// <param name="requestContainer">The dependency injection container for the request.</param> /// <param name="contentType">The response content type.</param> /// <remarks>This signature uses types that are AspNet-specific.</remarks> public ODataBatchContent(IEnumerable <ODataBatchResponseItem> responses, IServiceProvider requestContainer, MediaTypeHeaderValue contentType) { this.Initialize(responses, requestContainer); if (contentType == null) { contentType = MediaTypeHeaderValue.Parse( String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid())); } Headers.ContentType = contentType; ODataVersion version = _writerSettings.Version ?? ODataVersionConstraint.DefaultODataVersion; Headers.TryAddWithoutValidation(ODataVersionConstraint.ODataServiceVersionHeader, ODataUtils.ODataVersionToString(version)); }
private static string ComputeQueryClause(ODataUri odataUri, ODataVersion version) { if (odataUri != null) { if (odataUri.SelectAndExpand != null) { return(CreateSelectExpandContextUriSegment(odataUri.SelectAndExpand)); } else if (odataUri.Apply != null) { return(CreateApplyUriSegment(odataUri.Apply)); } } return(null); }
/// <summary>Constructor.</summary> /// <param name="format">The format for this input context.</param> /// <param name="messageStream">The stream to read data from.</param> /// <param name="contentType">The content type of the message to read.</param> /// <param name="encoding">The encoding to use to read the input.</param> /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param> /// <param name="version">The OData protocol version to be used for reading the payload.</param> /// <param name="readingResponse">true if reading a response message; otherwise false.</param> /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param> /// <param name="model">The model to use.</param> /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param> /// <param name="payloadKindDetectionState">JSON Ligth specific state stored during payload kind detection (or null if no payload kind detection happened).</param> internal ODataJsonLightInputContext( ODataFormat format, Stream messageStream, MediaType contentType, Encoding encoding, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver, ODataJsonLightPayloadKindDetectionState payloadKindDetectionState) : this(format, CreateTextReaderForMessageStreamConstructor(messageStream, encoding), contentType, messageReaderSettings, version, readingResponse, synchronous, model, urlResolver, payloadKindDetectionState) { DebugUtils.CheckNoExternalCallers(); }
/// <inheritdoc/> public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType) { // call base to validate parameters base.GetPerRequestFormatterInstance(type, request, mediaType); if (Request != null && Request == request) { // If the request is already set on this formatter, return itself. return(this); } else { ODataVersion version = GetODataResponseVersion(request); return(new ODataMediaTypeFormatter(this, version, request)); } }
public void TestGetNetflixData() { HTTPResponse samples = new HTTPResponse(); //FileResponseSamples fileResponseSamples = new FileResponseSamples(); string atomFormat = "application/atom+xml"; string jsonFormat = "application/json"; string localBaseUri = "http://localhost:8090/odata"; string netflixBaseUri = "http://odata.netflix.com/v2/Catalog/"; string stackoverflowBaseUri = "http://data.stackexchange.com/stackoverflow/atom/"; ODataVersion baseVersion = ODataVersion.V2; ODataVersion maxVersion = ODataVersion.V3; var model = samples.GetMetadata(netflixBaseUri + "$metadata"); samples.ExecuteNetflixRequest(model, "NetflixGenres"); }
private ODataMediaTypeFormatter(ODataMediaTypeFormatter formatter, ODataVersion version, HttpRequestMessage request) { Contract.Assert(formatter._serializerProvider != null); Contract.Assert(formatter._deserializerProvider != null); Contract.Assert(formatter._payloadKinds != null); Contract.Assert(request != null); // Parameter 1: formatter // Execept for the other two parameters, this constructor is a copy constructor, and we need to copy // everything on the other instance. // Parameter 1A: Copy this class's private fields and internal properties. _serializerProvider = formatter._serializerProvider; _deserializerProvider = formatter._deserializerProvider; _payloadKinds = formatter._payloadKinds; MessageReaderQuotas = formatter.MessageReaderQuotas; MessageWriterQuotas = formatter.MessageWriterQuotas; // Parameter 1B: Copy the base class's properties. foreach (MediaTypeMapping mediaTypeMapping in formatter.MediaTypeMappings) { // MediaTypeMapping doesn't support clone, and its public surface area is immutable anyway. MediaTypeMappings.Add(mediaTypeMapping); } RequiredMemberSelector = formatter.RequiredMemberSelector; foreach (Encoding supportedEncoding in formatter.SupportedEncodings) { // Per-request formatters share the encoding instances with the parent formatter SupportedEncodings.Add(supportedEncoding); } foreach (MediaTypeHeaderValue supportedMediaType in formatter.SupportedMediaTypes) { // Per-request formatters share the media type instances with the parent formatter SupportedMediaTypes.Add(supportedMediaType); } // Parameter 2: version _version = version; // Parameter 3: request _request = request; }
/// <summary> /// Creates the default settings for a given <see cref="ODataFormat"/>. /// </summary> /// <param name="format">The format for the message writer settings to create.</param> /// <param name="version">Version of the OData protocol.</param> /// <param name="baseUri">Base uri for all relative Uris.</param> /// <param name="enableMessageStreamDisposal">When set to true, the writer will dispose the message stream. When set to false, the message stream will not be disposed.</param> /// <returns>The default message writer settings for the specified <paramref name="format"/>.</returns> private static ODataMessageWriterSettings GetDefaultMessageWriterSettings( ODataFormat format, Uri baseUri, bool enableMessageStreamDisposal, ODataVersion version = ODataVersion.V4) { var settings = new ODataMessageWriterSettings() { Version = version, BaseUri = baseUri, EnableMessageStreamDisposal = enableMessageStreamDisposal, }; settings.SetServiceDocumentUri(new Uri("http://odata.org/test")); settings.SetContentType(format); return(settings); }
private static string ComputeQueryClause(ODataUri odataUri, ODataVersion version) { if (odataUri != null) { // TODO: Figure out how to deal with $select after $apply if (odataUri.Apply != null) { return(CreateApplyUriSegment(odataUri.Apply)); } else { return(CreateSelectExpandContextUriSegment(odataUri.SelectAndExpand)); } } return(null); }
/// <summary> /// Asynchronously creates an instance of the input context for this format. /// </summary> /// <param name="readerPayloadKind">The <see cref="ODataPayloadKind"/> to read.</param> /// <param name="message">The message to use.</param> /// <param name="contentType">The content type of the message to read.</param> /// <param name="encoding">The encoding to use.</param> /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param> /// <param name="version">The OData protocol version to be used for reading the payload.</param> /// <param name="readingResponse">true if reading a response message; otherwise false.</param> /// <param name="model">The model to use.</param> /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param> /// <param name="payloadKindDetectionFormatState">Format specific state stored during payload kind detection /// using the <see cref="ODataPayloadKindDetectionInfo.SetPayloadKindDetectionFormatState"/>.</param> /// <returns>Task which when completed returned the newly created input context.</returns> internal override Task <ODataInputContext> CreateInputContextAsync( ODataPayloadKind readerPayloadKind, ODataMessage message, MediaType contentType, Encoding encoding, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, IEdmModel model, IODataUrlResolver urlResolver, object payloadKindDetectionFormatState) { ExceptionUtils.CheckArgumentNotNull(message, "message"); ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings"); throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataMetadataFormat_CreateInputContextAsync)); }
/// <summary> /// Indexer to get the cached item when given the ODataVersion. /// </summary> /// <param name="version">The ODataVersion to look up.</param> /// <returns>The cached item.</returns> internal T this[ODataVersion version] { get { switch (version) { case ODataVersion.V4: return(this.v4.Value); case ODataVersion.V401: return(this.v401.Value); default: throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataVersionCache_UnknownVersion)); } } }
/// <summary> /// Initializes a new instance of the <see cref="ODataMediaTypeFormatter"/> class. /// </summary> /// <param name="formatter">The <see cref="ODataMediaTypeFormatter"/> to copy settings from.</param> /// <param name="version">The OData version that this formatter supports.</param> /// <param name="request">The <see cref="HttpRequestMessage"/> for the per-request formatter instance.</param> /// <remarks>This is a copy constructor to be used in <see cref="GetPerRequestFormatterInstance"/>.</remarks> internal ODataMediaTypeFormatter(ODataMediaTypeFormatter formatter, ODataVersion version, HttpRequestMessage request) : base(formatter) { if (request == null) { throw Error.ArgumentNull("request"); } Contract.Assert(formatter._serializerProvider != null); Contract.Assert(formatter._deserializerProvider != null); Contract.Assert(formatter._payloadKinds != null); // Parameter 1: formatter // Execept for the other two parameters, this constructor is a copy constructor, and we need to copy // everything on the other instance. // Copy this class's private fields and internal properties. _serializerProvider = formatter._serializerProvider; _deserializerProvider = formatter._deserializerProvider; _payloadKinds = formatter._payloadKinds; // Parameter 2: version _version = version; // Parameter 3: request Request = request; if (_serializerProvider.GetType() == typeof(ODataSerializerProviderProxy)) { _serializerProvider = new ODataSerializerProviderProxy { RequestContainer = request.GetRequestContainer() }; } if (_deserializerProvider.GetType() == typeof(ODataDeserializerProviderProxy)) { _deserializerProvider = new ODataDeserializerProviderProxy { RequestContainer = request.GetRequestContainer() }; } BaseAddressFactory = formatter.BaseAddressFactory; }
internal static Task <HttpResponseMessage> CreateODataBatchResponseAsync(this HttpRequestMessage request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas) { Contract.Assert(request != null); ODataVersion odataVersion = ODataMediaTypeFormatter.GetODataResponseVersion(request); IServiceProvider requestContainer = request.GetRequestContainer(); ODataMessageWriterSettings writerSettings = requestContainer.GetRequiredService <ODataMessageWriterSettings>(); writerSettings.Version = odataVersion; writerSettings.MessageQuotas = messageQuotas; HttpResponseMessage response = request.CreateResponse(HttpStatusCode.OK); response.Content = new ODataBatchContent(responses, requestContainer); return(Task.FromResult(response)); }
internal static object ConvertFromComplexOrCollectionValue(string value, ODataVersion version, IEdmModel model, IEdmTypeReference typeReference) { object obj3; ODataMessageReaderSettings messageReaderSettings = new ODataMessageReaderSettings(); using (StringReader reader = new StringReader(value)) { using (ODataJsonInputContext context = new ODataJsonInputContext(ODataFormat.VerboseJson, reader, messageReaderSettings, version, false, true, model, null)) { ODataJsonPropertyAndValueDeserializer deserializer = new ODataJsonPropertyAndValueDeserializer(context); deserializer.ReadPayloadStart(false); object obj2 = deserializer.ReadNonEntityValue(typeReference, null, null, true); deserializer.ReadPayloadEnd(false); obj3 = obj2; } } return obj3; }
/// <summary> /// Initializes a new instance of the <see cref="ODataBatchContent"/> class. /// </summary> /// <param name="responses">The batch responses.</param> /// <param name="requestContainer">The dependency injection container for the request.</param> /// <param name="contentType">The response content type.</param> /// <remarks>This signature uses types that are AspNetCore-specific.</remarks> public ODataBatchContent(IEnumerable <ODataBatchResponseItem> responses, IServiceProvider requestContainer, string contentType) { Initialize(responses, requestContainer); // Set the Content-Type header for existing batch formats if (contentType == null) { contentType = String.Format( CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid()); } Headers[HeaderNames.ContentType] = contentType; ODataVersion version = _writerSettings.Version ?? ODataVersionConstraint.DefaultODataVersion; Headers.Add(ODataVersionConstraint.ODataServiceVersionHeader, ODataUtils.ODataVersionToString(version)); }
protected static ODataMessageReader CreateODataMessageReader(IODataResponseMessage responseMessage, ResponseInfo responseInfo, ref ODataPayloadKind payloadKind) { ODataMessageReaderSettings settings = responseInfo.ReadHelper.CreateSettings(ReadingEntityInfo.BufferAndCacheEntryPayload); ODataMessageReader odataMessageReader = responseInfo.ReadHelper.CreateReader(responseMessage, settings); if (payloadKind == ODataPayloadKind.Unsupported) { var payloadKinds = odataMessageReader.DetectPayloadKind().ToList(); if (payloadKinds.Count == 0) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidResponsePayload(responseInfo.DataNamespace)); } // Pick the first payload kind detected by ODataLib and use that to parse the exception. // The only exception being payload with entity reference link(s). If one of the payload kinds // is reference links, then we need to give preference to reference link payloads. ODataPayloadKindDetectionResult detectionResult = payloadKinds.FirstOrDefault(k => k.PayloadKind == ODataPayloadKind.EntityReferenceLink || k.PayloadKind == ODataPayloadKind.EntityReferenceLinks); if (detectionResult == null) { ODataVersion dataServiceVersion = responseMessage.GetDataServiceVersion(CommonUtil.ConvertToODataVersion(responseInfo.MaxProtocolVersion)); // if its a collection or a Property we should choose collection if its less than V3, this enables older service operations on Execute if (dataServiceVersion < ODataVersion.V3 && payloadKinds.Any(pk => pk.PayloadKind == ODataPayloadKind.Property) && payloadKinds.Any(pk => pk.PayloadKind == ODataPayloadKind.Collection)) { detectionResult = payloadKinds.Single(pk => pk.PayloadKind == ODataPayloadKind.Collection); } else { detectionResult = payloadKinds.First(); } } // Astoria client only supports atom, jsonverbose, jsonlight and raw value payloads. if (detectionResult.Format != ODataFormat.Atom && detectionResult.Format != ODataFormat.VerboseJson && detectionResult.Format != ODataFormat.Json && detectionResult.Format != ODataFormat.RawValue) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidContentTypeEncountered(responseMessage.GetHeader(XmlConstants.HttpContentType))); } payloadKind = detectionResult.PayloadKind; } return(odataMessageReader); }
public static string ConvertToUriLiteral(object value, ODataVersion version, IEdmModel model) { if (value == null) { value = new ODataNullValue(); } if (model == null) { model = Microsoft.OData.Edm.Library.EdmCoreModel.Instance; } ODataNullValue nullValue = value as ODataNullValue; if (nullValue != null) { return(ExpressionConstants.KeywordNull); } ODataCollectionValue collectionValue = value as ODataCollectionValue; if (collectionValue != null) { return(ODataUriConversionUtils.ConvertToUriCollectionLiteral(collectionValue, model, version)); } ODataComplexValue complexValue = value as ODataComplexValue; if (complexValue != null) { return(ODataUriConversionUtils.ConvertToUriComplexLiteral(complexValue, model, version)); } ODataEnumValue enumValue = value as ODataEnumValue; if (enumValue != null) { return(ODataUriConversionUtils.ConvertToUriEnumLiteral(enumValue, version)); } // Try to convert uints to their underlying type first according to the model. value = model.ConvertToUnderlyingTypeIfUIntValue(value); return(ODataUriConversionUtils.ConvertToUriPrimitiveLiteral(value, version)); }
/// <summary> /// Initializes a new instance of the <see cref="ODataBatchContent"/> class. /// </summary> /// <param name="responses">The batch responses.</param> /// <param name="writerSettings">The <see cref="ODataMessageWriterSettings"/>.</param> public ODataBatchContent(IEnumerable <ODataBatchResponseItem> responses, ODataMessageWriterSettings writerSettings) { if (responses == null) { throw Error.ArgumentNull("responses"); } if (writerSettings == null) { throw Error.ArgumentNull("writerSettings"); } Responses = responses; _writerSettings = writerSettings; Headers.ContentType = MediaTypeHeaderValue.Parse(String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid())); ODataVersion version = _writerSettings.Version ?? HttpRequestMessageProperties.DefaultODataVersion; Headers.TryAddWithoutValidation(HttpRequestMessageProperties.ODataServiceVersionHeader, ODataUtils.ODataVersionToString(version)); }
internal static Task <HttpResponseMessage> CreateODataBatchResponseAsync(this HttpRequestMessage request, IEnumerable <ODataBatchResponseItem> responses, ODataMessageQuotas messageQuotas) { Contract.Assert(request != null); ODataVersion odataVersion = ODataMediaTypeFormatter.GetODataResponseVersion(request); ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { Version = odataVersion, Indent = true, DisableMessageStreamDisposal = true, MessageQuotas = messageQuotas }; HttpResponseMessage response = request.CreateResponse(HttpStatusCode.OK); response.Content = new ODataBatchContent(responses, writerSettings); return(Task.FromResult(response)); }
private static TestMediaTypeWithFormat GetResponseType(ODataVersion version, Action <ODataMessageWriterSettings> configureSettings) { var settings = new ODataMessageWriterSettings { Version = version }; configureSettings(settings); ODataMediaType mediaType; Encoding encoding; var format = MediaTypeUtils.GetContentTypeFromSettings(settings, ODataPayloadKind.Resource, ODataMediaTypeResolver.GetMediaTypeResolver(null), out mediaType, out encoding); Assert.NotNull(mediaType); Assert.NotNull(format); return(new TestMediaTypeWithFormat { MediaType = mediaType, Format = format }); }