internal Serializer(System.Data.Services.RequestDescription requestDescription, Uri absoluteServiceUri, IDataService service, string httpETagHeaderValue) { this.requestDescription = requestDescription; this.absoluteServiceUri = absoluteServiceUri; this.service = service; this.httpETagHeaderValue = httpETagHeaderValue; }
internal Deserializer(bool update, IDataService dataService, UpdateTracker tracker, System.Data.Services.RequestDescription requestDescription) { this.service = dataService; this.tracker = tracker; this.update = update; this.description = requestDescription; }
private static object GetEntityResourceToModify(System.Data.Services.RequestDescription description, IDataService service, bool allowCrossReferencing, out ResourceSetWrapper entityContainer, out int entityResourceIndex) { if (!allowCrossReferencing && (description.RequestExpression == null)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_ResourceCanBeCrossReferencedOnlyForBindOperation); } entityResourceIndex = GetIndexOfEntityResourceToModify(description); entityContainer = description.SegmentInfos[entityResourceIndex].TargetContainer; DataServiceHostWrapper host = service.OperationContext.Host; if (host.HttpVerb == HttpVerbs.PUT) { DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteReplace); } else if ((host.HttpVerb == HttpVerbs.MERGE) || (host.HttpVerb == HttpVerbs.PATCH)) { DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteMerge); } else { DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteMerge | EntitySetRights.WriteReplace); } object obj2 = service.GetResource(description, entityResourceIndex, null); if (obj2 == null) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_DereferencingNullPropertyValue(description.SegmentInfos[entityResourceIndex].Identifier)); } return(obj2); }
internal static object GetResourceToModify(System.Data.Services.RequestDescription description, IDataService service, bool allowCrossReferencing, out object entityResource, out ResourceSetWrapper entityContainer, bool checkETag) { int num; int num2; if ((description.TargetKind == RequestTargetKind.OpenPropertyValue) || (description.TargetKind == RequestTargetKind.PrimitiveValue)) { num = description.SegmentInfos.Length - 3; } else { num = description.SegmentInfos.Length - 2; } entityResource = GetEntityResourceToModify(description, service, allowCrossReferencing, out entityContainer, out num2); object targetResource = entityResource; for (int i = num2 + 1; i <= num; i++) { if (!description.SegmentInfos[i].IsTypeIdentifierSegment) { targetResource = service.Updatable.GetValue(targetResource, description.SegmentInfos[i].Identifier); } } if ((checkETag && !IsCrossReferencedSegment(description.SegmentInfos[num], service)) && (description.TargetKind != RequestTargetKind.MediaResource)) { service.Updatable.SetETagValues(entityResource, entityContainer); } return(targetResource); }
internal object HandlePostRequest() { object targetResourceToBind; System.Data.Services.RequestDescription requestDescription = this.RequestDescription; if (requestDescription.LinkUri) { Uri referencedUri = (Uri)this.Deserialize(null); targetResourceToBind = this.GetTargetResourceToBind(referencedUri, true); HandleBindOperation(requestDescription, targetResourceToBind, this.Service, this.Tracker); return(targetResourceToBind); } if (requestDescription.LastSegmentInfo.TargetContainer != null) { DataServiceConfiguration.CheckResourceRights(requestDescription.LastSegmentInfo.TargetContainer, EntitySetRights.WriteAppend); } targetResourceToBind = this.ReadEntity(); if (requestDescription.TargetSource == RequestTargetSource.Property) { HandleBindOperation(requestDescription, targetResourceToBind, this.Service, this.Tracker); return(targetResourceToBind); } this.Tracker.TrackAction(targetResourceToBind, requestDescription.LastSegmentInfo.TargetContainer, UpdateOperations.Add); return(targetResourceToBind); }
internal static Deserializer CreateDeserializer(System.Data.Services.RequestDescription description, IDataService dataService, bool update, UpdateTracker tracker) { string str; Encoding encoding; HttpProcessUtility.ReadContentType(dataService.OperationContext.Host.RequestContentType, out str, out encoding); if (DataServiceActionProviderWrapper.IsServiceActionRequest(description)) { return(new ParameterDeserializer(update, dataService, tracker, description)); } if ((description.TargetKind == RequestTargetKind.OpenPropertyValue) || (description.TargetKind == RequestTargetKind.PrimitiveValue)) { return(new RawValueDeserializer(update, dataService, tracker, description)); } if (description.TargetKind == RequestTargetKind.MediaResource) { return(new MediaResourceDeserializer(update, dataService, tracker, description)); } if (((description.TargetKind == RequestTargetKind.Primitive) || (description.TargetKind == RequestTargetKind.ComplexObject)) || ((description.TargetKind == RequestTargetKind.Collection) || (description.TargetKind == RequestTargetKind.OpenProperty))) { return(new PropertyDeserializer(update, dataService, tracker, description)); } if (description.LinkUri) { return(new EntityReferenceLinkDeserializer(update, dataService, tracker, description)); } if (description.TargetKind != RequestTargetKind.Resource) { throw new DataServiceException(0x19f, System.Data.Services.Strings.RequestUriProcessor_MethodNotAllowed); } return(new EntityDeserializer(update, dataService, tracker, description)); }
internal RequestDescription(RequestDescription other, Expression resultExpression, System.Data.Services.Providers.RootProjectionNode rootProjectionNode) { this.containerName = other.containerName; this.mimeType = other.mimeType; this.resultUri = other.resultUri; this.segmentInfos = other.SegmentInfos; this.rootProjectionNode = rootProjectionNode; this.countOption = other.countOption; this.SkipTokenExpressionCount = other.SkipTokenExpressionCount; this.SkipTokenProperties = other.SkipTokenProperties; this.countValue = other.countValue; this.responseVersion = other.ResponseVersion; this.actualResponseVersion = other.ActualResponseVersion; this.PreferenceApplied = other.PreferenceApplied; if (resultExpression == null) { this.segmentInfos = other.SegmentInfos; } else { int index = other.SegmentInfos.Length - 1; SegmentInfo info = other.SegmentInfos[index]; info.RequestExpression = resultExpression; } }
internal Deserializer(Deserializer parent) { this.recursionDepth = parent.recursionDepth; this.service = parent.service; this.tracker = parent.tracker; this.update = parent.update; this.description = parent.description; }
internal static Dictionary <string, object> ReadPayloadParameters(System.Data.Services.SegmentInfo actionSegment, IDataService dataService) { System.Data.Services.RequestDescription description = new System.Data.Services.RequestDescription(new System.Data.Services.SegmentInfo[] { actionSegment }, RequestUriProcessor.GetResultUri(dataService.OperationContext)); description.VerifyRequestVersion(System.Data.Services.RequestDescription.Version3Dot0, dataService); using (Deserializer deserializer = CreateDeserializer(description, dataService, false, UpdateTracker.CreateUpdateTracker(dataService))) { return((Dictionary <string, object>)deserializer.Deserialize(actionSegment)); } }
internal ResponseBodyWriter(bool hasMoved, IDataService service, IEnumerator queryResults, RequestDescription requestDescription, IODataResponseMessage responseMessage, ODataPayloadKind payloadKind) { this.hasMoved = hasMoved; this.service = service; this.queryResults = queryResults; this.requestDescription = requestDescription; this.responseMessage = responseMessage; this.payloadKind = payloadKind; this.encoding = HttpProcessUtility.EncodingFromAcceptCharset(this.service.OperationContext.Host.RequestAcceptCharSet); if ((((payloadKind == ODataPayloadKind.Entry) || (payloadKind == ODataPayloadKind.Feed)) || ((payloadKind == ODataPayloadKind.Property) || (payloadKind == ODataPayloadKind.Collection))) || (((payloadKind == ODataPayloadKind.EntityReferenceLink) || (payloadKind == ODataPayloadKind.EntityReferenceLinks)) || (((payloadKind == ODataPayloadKind.Error) || (payloadKind == ODataPayloadKind.ServiceDocument)) || (payloadKind == ODataPayloadKind.Parameter)))) { DataServiceHostWrapper host = service.OperationContext.Host; if (WebUtil.GetEffectiveMaxResponseVersion(service.Configuration.DataServiceBehavior.MaxProtocolVersion, host.RequestMaxVersion) > RequestDescription.Version2Dot0) { bool isEntityOrFeed = (payloadKind == ODataPayloadKind.Entry) || (payloadKind == ODataPayloadKind.Feed); if (WebUtil.ResponseMediaTypeWouldBeJsonLight(host.RequestAccept, isEntityOrFeed)) { requestDescription.VerifyAndRaiseResponseVersion(RequestDescription.Version3Dot0, service); host.ResponseVersion = RequestDescription.Version3Dot0.ToString() + ";"; } } } if (this.requestDescription.TargetKind == RequestTargetKind.MediaResource) { this.mediaResourceStream = service.StreamProvider.GetReadStream(this.queryResults.Current, RequestDescription.GetStreamProperty(this.requestDescription), this.service.OperationContext); } else if (payloadKind != ODataPayloadKind.BinaryValue) { string requestAcceptCharSet = this.service.OperationContext.Host.RequestAcceptCharSet; if (string.IsNullOrEmpty(requestAcceptCharSet) || (requestAcceptCharSet == "*")) { requestAcceptCharSet = "UTF-8"; } if ((payloadKind == ODataPayloadKind.Value) && !string.IsNullOrEmpty(this.requestDescription.MimeType)) { this.messageWriter = CreateMessageWriter(this.AbsoluteServiceUri, this.service, this.requestDescription.ActualResponseVersion, responseMessage, ODataFormat.RawValue); } else { this.messageWriter = CreateMessageWriter(this.AbsoluteServiceUri, this.service, this.requestDescription.ActualResponseVersion, responseMessage, this.service.OperationContext.Host.RequestAccept, requestAcceptCharSet); } try { this.contentFormat = ODataUtils.SetHeadersForPayload(this.messageWriter, payloadKind); if ((payloadKind == ODataPayloadKind.Value) && !string.IsNullOrEmpty(this.requestDescription.MimeType)) { responseMessage.SetHeader("Content-Type", this.requestDescription.MimeType); } } catch (ODataContentTypeException exception) { throw new DataServiceException(0x19f, null, System.Data.Services.Strings.DataServiceException_UnsupportedMediaType, null, exception); } string headerValue = this.requestDescription.ResponseVersion.ToString() + ";"; responseMessage.SetHeader("DataServiceVersion", headerValue); } }
internal ODataMessageReaderDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription, bool enableWcfDataServicesServerBehavior) : base(update, dataService, tracker, requestDescription) { System.Data.Services.ODataRequestMessage requestMessage = new System.Data.Services.ODataRequestMessage(dataService.OperationContext.Host); if (WebUtil.CompareMimeType(requestMessage.ContentType, "*/*")) { requestMessage.ContentType = "application/atom+xml"; } this.messageReader = new ODataMessageReader(requestMessage, WebUtil.CreateMessageReaderSettings(dataService, enableWcfDataServicesServerBehavior), dataService.Provider.GetMetadataModel(base.Service.OperationContext)); this.contentFormat = System.Data.Services.ContentFormat.Unknown; }
protected object GetTargetResourceToBind(Uri referencedUri, bool checkNull) { System.Data.Services.RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service, true); object obj2 = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null); if (checkNull) { WebUtil.CheckResourceExists(obj2 != null, description.LastSegmentInfo.Identifier); } return(obj2); }
/// <summary>Initializes a new base Serializer, ready to write out a description.</summary> /// <param name="requestDescription">Description for the requested results.</param> /// <param name="absoluteServiceUri">Base URI from which resources should be resolved.</param> /// <param name="service">Service with configuration and provider from which metadata should be gathered.</param> /// <param name="httpETagHeaderValue">HTTP ETag header value.</param> internal Serializer(RequestDescription requestDescription, Uri absoluteServiceUri, IDataService service, string httpETagHeaderValue) { Debug.Assert(requestDescription != null, "requestDescription != null"); Debug.Assert(absoluteServiceUri != null, "absoluteServiceUri != null"); Debug.Assert(service != null, "service != null"); this.requestDescription = requestDescription; this.absoluteServiceUri = absoluteServiceUri; this.service = service; this.httpETagHeaderValue = httpETagHeaderValue; }
internal static int GetIndexOfEntityResourceToModify(System.Data.Services.RequestDescription description) { if (description.LinkUri) { return(description.SegmentInfos.Length - 3); } for (int i = description.SegmentInfos.Length - 1; i >= 0; i--) { if ((description.SegmentInfos[i].TargetKind == RequestTargetKind.Resource) && description.SegmentInfos[i].SingleResult) { return(i); } } return(-1); }
internal static object HandleBindOperation(System.Data.Services.RequestDescription description, object linkResource, IDataService service, UpdateTracker tracker) { ResourceSetWrapper wrapper; object target = GetEntityResourceToModify(description, service, true, out wrapper); description.UpdateAndCheckEpmFeatureVersion(wrapper, service); tracker.TrackAction(target, wrapper, UpdateOperations.Change); if (description.IsSingleResult) { service.Updatable.SetReference(target, description.Property.Name, linkResource); return(target); } service.Updatable.AddReferenceToCollection(target, description.Property.Name, linkResource); return(target); }
internal static void ModifyResource(System.Data.Services.RequestDescription description, object resourceToBeModified, object requestValue, IDataService service) { if ((description.TargetKind == RequestTargetKind.OpenProperty) || (description.TargetKind == RequestTargetKind.OpenPropertyValue)) { SetOpenPropertyValue(resourceToBeModified, description.ContainerName, requestValue, service); } else if (description.TargetKind == RequestTargetKind.MediaResource) { SetStreamPropertyValue(resourceToBeModified, (Stream)requestValue, service, description); } else { SetPropertyValue(description.LastSegmentInfo.ProjectedProperty, resourceToBeModified, requestValue, service); } }
private RequestQueryProcessor(IDataService service, RequestDescription description) { this.service = service; this.description = description; this.orderApplied = false; this.skipCount = null; this.topCount = null; this.queryExpression = description.RequestExpression; this.filterQueryApplicable = (((description.TargetKind == RequestTargetKind.Resource) || (description.TargetKind == RequestTargetKind.OpenProperty)) || (description.TargetKind == RequestTargetKind.ComplexObject)) || (description.CountOption == RequestQueryCountOption.ValueOnly); this.setQueryApplicable = ((description.TargetKind == RequestTargetKind.Resource) && !description.IsSingleResult) || (description.CountOption == RequestQueryCountOption.ValueOnly); this.pagingApplicable = (((description.TargetKind == RequestTargetKind.Resource) && !description.IsSingleResult) && ((description.CountOption != RequestQueryCountOption.ValueOnly) && !description.IsRequestForEnumServiceOperation)) && ((service.OperationContext.Host.HttpVerb == HttpVerbs.GET) || (description.SegmentInfos[0].TargetSource == RequestTargetSource.ServiceOperation)); this.appliedCustomPaging = false; this.expandPaths = null; this.expandPathsAsText = null; this.rootProjectionNode = null; this.orderingParser = null; this.topLevelOrderingInfo = null; }
private static bool IsQueryRequired(System.Data.Services.RequestDescription requestDescription, object requestValue) { if ((((requestDescription.TargetKind == RequestTargetKind.PrimitiveValue) || (requestDescription.TargetKind == RequestTargetKind.Primitive)) || ((requestDescription.TargetKind == RequestTargetKind.OpenPropertyValue) || (requestDescription.TargetKind == RequestTargetKind.MediaResource))) || ((requestDescription.TargetKind == RequestTargetKind.ComplexObject) || (requestDescription.TargetKind == RequestTargetKind.Collection))) { return(true); } if (requestDescription.TargetKind == RequestTargetKind.OpenProperty) { ResourceType targetResourceType = requestDescription.LastSegmentInfo.TargetResourceType; if ((requestValue == null) || (targetResourceType.ResourceTypeKind == ResourceTypeKind.Primitive)) { return(true); } if (targetResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType) { return(true); } } return(false); }
internal static RequestDescription CreateSingleResultRequestDescription(RequestDescription description, object entity) { SegmentInfo info = new SegmentInfo { RequestExpression = Expression.Constant(entity), RequestEnumerable = new object[] { entity }, TargetKind = description.TargetKind, TargetSource = description.TargetSource, SingleResult = true, ProjectedProperty = description.Property, TargetResourceType = description.TargetResourceType, TargetContainer = description.LastSegmentInfo.TargetContainer, Identifier = description.LastSegmentInfo.Identifier }; SegmentInfo[] segmentInfos = description.SegmentInfos; segmentInfos[segmentInfos.Length - 1] = info; return(new RequestDescription(segmentInfos, description.ResultUri) { responseVersion = description.ResponseVersion, actualResponseVersion = description.ActualResponseVersion, PreferenceApplied = description.PreferenceApplied }); }
internal object ReadEntity() { System.Data.Services.RequestDescription requestDescription = this.RequestDescription; if (requestDescription.TargetKind == RequestTargetKind.Resource) { this.RequestDescription.UpdateAndCheckEpmFeatureVersion(this.description.LastSegmentInfo.TargetContainer, this.Service); } System.Data.Services.SegmentInfo lastSegmentInfo = requestDescription.LastSegmentInfo; if (!this.Update) { lastSegmentInfo = new System.Data.Services.SegmentInfo { TargetKind = lastSegmentInfo.TargetKind, TargetSource = lastSegmentInfo.TargetSource, SingleResult = true, ProjectedProperty = lastSegmentInfo.ProjectedProperty, TargetResourceType = lastSegmentInfo.TargetResourceType, TargetContainer = lastSegmentInfo.TargetContainer, Identifier = lastSegmentInfo.Identifier }; } return(this.Deserialize(lastSegmentInfo)); }
/// <summary>Initializes a new <see cref="ResponseBodyWriter"/> that can write the body of a response.</summary> /// <param name="encoding">Encoding, if available.</param> /// <param name="hasMoved">Whether <paramref name="queryResults"/> has already moved.</param> /// <param name="service">Service for the request being processed.</param> /// <param name="queryResults">Enumerator for results.</param> /// <param name="requestDescription">Description of request made to the system.</param> /// <param name="responseFormat">Content format for response.</param> internal ResponseBodyWriter( Encoding encoding, bool hasMoved, IDataService service, IEnumerator queryResults, RequestDescription requestDescription, ContentFormat responseFormat) { Debug.Assert(responseFormat != ContentFormat.Unknown, "responseFormat != ContentFormat.Unknown"); this.encoding = encoding; this.hasMoved = hasMoved; this.service = service; this.queryResults = queryResults; this.requestDescription = requestDescription; this.responseFormat = responseFormat; if (this.requestDescription.TargetKind == RequestTargetKind.MediaResource) { // Note that GetReadStream will set the ResponseETag before it returns this.mediaResourceStream = service.StreamProvider.GetReadStream(this.queryResults.Current, this.service.OperationContext); } }
/// <summary>Initializes a new RequestDescription based on an existing one.</summary> /// <param name="other">Other description to base new description on.</param> /// <param name="queryResults">Query results for new request description.</param> /// <param name="rootProjectionNode">Projection segment describing the projections on the top level of the query.</param> internal RequestDescription( RequestDescription other, IEnumerable queryResults, RootProjectionNode rootProjectionNode) { Debug.Assert( queryResults == null || other.SegmentInfos != null, "queryResults == null || other.SegmentInfos != null -- otherwise there isn't a segment in which to replace the query."); Debug.Assert( rootProjectionNode == null || queryResults != null, "rootProjectionNode == null || queryResults != null -- otherwise there isn't a query to execute and expand"); this.containerName = other.containerName; this.mimeType = other.mimeType; this.usesContainerName = other.usesContainerName; this.resultUri = other.resultUri; this.segmentInfos = other.SegmentInfos; this.rootProjectionNode = rootProjectionNode; this.countOption = other.countOption; this.SkipTokenExpressionCount = other.SkipTokenExpressionCount; this.SkipTokenProperties = other.SkipTokenProperties; this.countValue = other.countValue; this.requireMinimumVersion = other.requireMinimumVersion; this.responseVersion = other.responseVersion; this.maxFeatureVersion = other.maxFeatureVersion; if (queryResults == null) { this.segmentInfos = other.SegmentInfos; } else { int lastSegmentIndex = other.SegmentInfos.Length - 1; SegmentInfo lastSegmentInfo = other.SegmentInfos[lastSegmentIndex]; lastSegmentInfo.RequestEnumerable = queryResults; } }
internal static bool TryGetMinResponseVersionForError(DataServiceHostWrapper host, Version maxProtocolVersion, out Version responseVersion) { responseVersion = null; try { Version version; if (((maxProtocolVersion > RequestDescription.Version2Dot0) && (host.RequestMaxVersion > RequestDescription.Version2Dot0)) && WebUtil.ResponseMediaTypeWouldBeJsonLight(host.RequestAccept, false)) { responseVersion = RequestDescription.Version3Dot0; } if (!host.TryGetMinDataServiceVersionFromWrappedHost(out version)) { return(responseVersion != null); } if ((responseVersion == null) || (version > responseVersion)) { responseVersion = version; } if (maxProtocolVersion < RequestDescription.Version3Dot0) { responseVersion = RequestDescription.DataServiceDefaultResponseVersion; return(true); } if (!RequestDescription.IsKnownRequestVersion(responseVersion) || (responseVersion > maxProtocolVersion)) { return(false); } return(true); } catch (Exception exception) { if (!CommonUtil.IsCatchableExceptionType(exception)) { throw; } } return(false); }
private Version GetMinDataServiceVersion(Version maxProtocolVersion) { if (this.requestMinVersion == null) { this.TryGetMinDataServiceVersionFromWrappedHost(out this.requestMinVersion); if ((maxProtocolVersion < RequestDescription.Version3Dot0) || (this.requestMinVersion == null)) { this.requestMinVersion = RequestDescription.DataServiceDefaultResponseVersion; } else { if (this.requestMinVersion > maxProtocolVersion) { throw DataServiceException.CreateBadRequestError(Strings.DataService_MinDSVGreaterThanMPV(this.requestMinVersion.ToString(2), maxProtocolVersion.ToString(2))); } if (!RequestDescription.IsKnownRequestVersion(this.requestMinVersion)) { throw DataServiceException.CreateBadRequestError(Strings.DataService_InvalidMinDSV(this.requestMinVersion.ToString(2), KnownDataServiceVersionsToString(GetMaxRequestVersionAllowed(maxProtocolVersion)))); } } } return(this.requestMinVersion); }
internal object HandlePutRequest() { object requestValue = null; object entityResource = null; ResourceSetWrapper entityContainer = null; string str; Encoding encoding; HttpProcessUtility.ReadContentType(this.Service.OperationContext.Host.RequestContentType, out str, out encoding); System.Data.Services.RequestDescription requestDescription = this.RequestDescription; if (((requestDescription.TargetKind == RequestTargetKind.MediaResource) || (requestDescription.TargetKind == RequestTargetKind.OpenPropertyValue)) || (requestDescription.TargetKind == RequestTargetKind.PrimitiveValue)) { requestValue = this.Deserialize(requestDescription.LastSegmentInfo); } else if (requestDescription.LinkUri) { Uri referencedUri = (Uri)this.Deserialize(null); object targetResourceToBind = this.GetTargetResourceToBind(referencedUri, true); entityResource = HandleBindOperation(requestDescription, targetResourceToBind, this.Service, this.Tracker); entityContainer = requestDescription.LastSegmentInfo.TargetContainer; } else { requestValue = this.ReadEntity(); if (((requestValue == null) && requestDescription.LastSegmentInfo.HasKeyValues) && (requestDescription.TargetSource == RequestTargetSource.EntitySet)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_CannotSetTopLevelResourceToNull(requestDescription.ResultUri.AbsoluteUri)); } } if (!requestDescription.LinkUri && IsQueryRequired(requestDescription, requestValue)) { object resourceToBeModified = GetResourceToModify(requestDescription, this.Service, false, out entityResource, out entityContainer, true); this.Tracker.TrackAction(entityResource, entityContainer, UpdateOperations.Change); ModifyResource(requestDescription, resourceToBeModified, requestValue, this.Service); } return(entityResource ?? requestValue); }
/// <summary> /// Create a new request description from the given request description and new entity as the result. /// </summary> /// <param name="description">Existing request description.</param> /// <param name="entity">entity that needs to be the result of the new request.</param> /// <param name="container">container to which the entity belongs to.</param> /// <returns>a new instance of request description containing information about the given entity.</returns> internal static RequestDescription CreateSingleResultRequestDescription( RequestDescription description, object entity, ResourceSetWrapper container) { // Create a new request description for the results that will be returned. SegmentInfo segmentInfo = new SegmentInfo(); segmentInfo.RequestEnumerable = new object[] { entity }; segmentInfo.TargetKind = description.TargetKind; segmentInfo.TargetSource = description.TargetSource; segmentInfo.SingleResult = true; segmentInfo.ProjectedProperty = description.Property; segmentInfo.TargetResourceType = container != null ? container.ResourceType : null; segmentInfo.TargetContainer = container; segmentInfo.Identifier = description.LastSegmentInfo.Identifier; #if DEBUG segmentInfo.AssertValid(); #endif SegmentInfo[] segmentInfos = description.SegmentInfos; segmentInfos[segmentInfos.Length - 1] = segmentInfo; RequestDescription resultDescription = new RequestDescription( segmentInfos, container != null ? container.Name : null, description.UsesContainerName, description.MimeType, description.ResultUri); resultDescription.requireMinimumVersion = description.RequireMinimumVersion; resultDescription.responseVersion = description.ResponseVersion; resultDescription.maxFeatureVersion = description.MaxFeatureVersion; return resultDescription; }
internal EntityReferenceLinkDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription) : base(update, dataService, tracker, requestDescription, true) { }
internal static object GetEntityResourceToModify(System.Data.Services.RequestDescription description, IDataService service, bool allowCrossReferencing, out ResourceSetWrapper entityContainer) { int num; return(GetEntityResourceToModify(description, service, allowCrossReferencing, out entityContainer, out num)); }
internal static bool IsNamedStream(RequestDescription description) { return(description.LastSegmentInfo.Identifier != "$value"); }
internal static ResourceProperty GetStreamProperty(RequestDescription description) { ResourceProperty property = null; if (IsNamedStream(description)) { property = description.TargetResourceType.TryResolvePropertyName(description.LastSegmentInfo.Identifier); } return property; }
internal RawValueDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription) : base(update, dataService, tracker, requestDescription, true) { }
internal static string GetAllowedMethods(DataServiceConfiguration configuration, RequestDescription description) { if ((description.TargetKind == RequestTargetKind.Metadata) || (description.TargetKind == RequestTargetKind.ServiceDirectory)) { return "GET"; } if (description.TargetKind == RequestTargetKind.Batch) { return "POST"; } int indexOfTargetEntityResource = description.GetIndexOfTargetEntityResource(); ResourceSetWrapper targetContainer = description.SegmentInfos[indexOfTargetEntityResource].TargetContainer; return GetAllowedMethods(configuration, targetContainer, description); }
private static void InvokeRequestExpression(RequestDescription description, IDataService service) { HttpVerbs httpVerb = service.OperationContext.Host.HttpVerb; bool flag = (httpVerb == HttpVerbs.POST) && (description.TargetSource == RequestTargetSource.ServiceOperation); if ((httpVerb == HttpVerbs.GET) || flag) { System.Data.Services.SegmentInfo lastSegmentInfo = description.LastSegmentInfo; if ((httpVerb == HttpVerbs.GET) && (description.TargetSource == RequestTargetSource.Property)) { lastSegmentInfo = description.SegmentInfos[description.GetIndexOfTargetEntityResource()]; } if ((lastSegmentInfo.RequestExpression != null) && (lastSegmentInfo.RequestEnumerable == null)) { lastSegmentInfo.RequestEnumerable = service.ExecutionProvider.GetResultEnumerableFromRequest(lastSegmentInfo); } } }
/// <summary>Gets a string with methods allowed on the target for the <paramref name="description"/>.</summary> /// <param name="configuration">configuration object which has the data</param> /// <param name="description">Description with target.</param> /// <returns>A string with methods allowed on the description; possibly null.</returns> internal static string GetAllowedMethods(DataServiceConfiguration configuration, RequestDescription description) { Debug.Assert(description != null, "description != null"); Debug.Assert( description.TargetKind != RequestTargetKind.Nothing, "description.TargetKind != RequestTargetKind.Void - otherwise it hasn't been determined yet"); Debug.Assert( description.TargetKind != RequestTargetKind.VoidServiceOperation, "description.TargetKind != RequestTargetKind.VoidServiceOperation - this method is only for containers"); if (description.TargetKind == RequestTargetKind.Metadata || description.TargetKind == RequestTargetKind.ServiceDirectory) { return XmlConstants.HttpMethodGet; } else if (description.TargetKind == RequestTargetKind.Batch) { return XmlConstants.HttpMethodPost; } else { int index = description.GetIndexOfTargetEntityResource(); Debug.Assert(index >= 0 && index < description.SegmentInfos.Length, "index >=0 && index <description.SegmentInfos.Length"); ResourceSetWrapper container = description.SegmentInfos[index].TargetContainer; return GetAllowedMethods(configuration, container, description); } }
internal ParameterDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription) : base(update, dataService, tracker, requestDescription, false) { }
internal static Dictionary<string, object> ReadPayloadParameters(System.Data.Services.SegmentInfo actionSegment, IDataService dataService) { System.Data.Services.RequestDescription description = new System.Data.Services.RequestDescription(new System.Data.Services.SegmentInfo[] { actionSegment }, RequestUriProcessor.GetResultUri(dataService.OperationContext)); description.VerifyRequestVersion(System.Data.Services.RequestDescription.Version3Dot0, dataService); using (Deserializer deserializer = CreateDeserializer(description, dataService, false, UpdateTracker.CreateUpdateTracker(dataService))) { return (Dictionary<string, object>) deserializer.Deserialize(actionSegment); } }
internal static string GetAllowedMethods(DataServiceConfiguration configuration, ResourceSetWrapper container, RequestDescription description) { if (container == null) { return(null); } StringBuilder builder = new StringBuilder(); EntitySetRights resourceSetRights = configuration.GetResourceSetRights(container.ResourceSet); if (description.IsSingleResult) { AppendRight(resourceSetRights, EntitySetRights.ReadSingle, "GET", builder); AppendRight(resourceSetRights, EntitySetRights.WriteReplace, "PUT", builder); if (description.TargetKind != RequestTargetKind.MediaResource) { AppendRight(resourceSetRights, EntitySetRights.WriteMerge, "MERGE", builder); AppendRight(resourceSetRights, EntitySetRights.WriteMerge, "PATCH", builder); AppendRight(resourceSetRights, EntitySetRights.WriteDelete, "DELETE", builder); } } else { AppendRight(resourceSetRights, EntitySetRights.ReadMultiple, "GET", builder); AppendRight(resourceSetRights, EntitySetRights.WriteAppend, "POST", builder); } return(builder.ToString()); }
internal static RequestDescription ProcessQuery(IDataService service, RequestDescription description) { if ((service.OperationContext.Host.HttpVerb != HttpVerbs.GET) && (description.SegmentInfos[0].TargetSource != RequestTargetSource.ServiceOperation)) { CheckV2EmptyQueryArguments(service); } if (((description.RequestExpression == null) || DataServiceActionProviderWrapper.IsServiceActionRequest(description)) || !typeof(IQueryable).IsAssignableFrom(description.RequestExpression.Type)) { CheckEmptyQueryArguments(service, false); return description; } RequestQueryProcessor processor = new RequestQueryProcessor(service, description); return processor.ProcessQuery(); }
internal static bool IsServiceActionRequest(RequestDescription description) { return IsServiceActionSegment(description.LastSegmentInfo); }
internal static string GetAllowedMethods(DataServiceConfiguration configuration, RequestDescription description) { if ((description.TargetKind == RequestTargetKind.Metadata) || (description.TargetKind == RequestTargetKind.ServiceDirectory)) { return("GET"); } if (description.TargetKind == RequestTargetKind.Batch) { return("POST"); } int indexOfTargetEntityResource = description.GetIndexOfTargetEntityResource(); ResourceSetWrapper targetContainer = description.SegmentInfos[indexOfTargetEntityResource].TargetContainer; return(GetAllowedMethods(configuration, targetContainer, description)); }
internal static bool IsNamedStream(RequestDescription description) { return (description.LastSegmentInfo.Identifier != "$value"); }
internal NonEntitySerializer(RequestDescription requestDescription, Uri absoluteServiceUri, IDataService service, ODataMessageWriter messageWriter) : base(requestDescription, absoluteServiceUri, service, null) { this.writer = messageWriter; }
/// <summary> /// Checks whether etag headers are allowed (both request and response) for this request. /// ETag request headers are mainly If-Match and If-None-Match headers /// ETag response header is written only when its valid to specify one of the above mentioned request headers. /// </summary> /// <param name="description">description about the request uri.</param> /// <returns>true if If-Match or If-None-Match are allowed request headers for this request, otherwise false.</returns> internal static bool IsETagHeaderAllowed(RequestDescription description) { // IfMatch and IfNone match request headers are allowed and etag response header must be written // only when the request targets a single resource, which does not have $count and $links segment and there are no $expands query option specified. return(description.IsSingleResult && description.CountOption != RequestQueryCountOption.ValueOnly && (description.RootProjectionNode == null || !description.RootProjectionNode.ExpansionsSpecified) && !description.LinkUri); }
internal static string GetAllowedMethods(DataServiceConfiguration configuration, ResourceSetWrapper container, RequestDescription description) { if (container == null) { return null; } StringBuilder builder = new StringBuilder(); EntitySetRights resourceSetRights = configuration.GetResourceSetRights(container.ResourceSet); if (description.IsSingleResult) { AppendRight(resourceSetRights, EntitySetRights.ReadSingle, "GET", builder); AppendRight(resourceSetRights, EntitySetRights.WriteReplace, "PUT", builder); if (description.TargetKind != RequestTargetKind.MediaResource) { AppendRight(resourceSetRights, EntitySetRights.WriteMerge, "MERGE", builder); AppendRight(resourceSetRights, EntitySetRights.WriteMerge, "PATCH", builder); AppendRight(resourceSetRights, EntitySetRights.WriteDelete, "DELETE", builder); } } else { AppendRight(resourceSetRights, EntitySetRights.ReadMultiple, "GET", builder); AppendRight(resourceSetRights, EntitySetRights.WriteAppend, "POST", builder); } return builder.ToString(); }
/// <summary> /// Checks whether etag headers are allowed (both request and response) for this request. /// ETag request headers are mainly If-Match and If-None-Match headers /// ETag response header is written only when its valid to specify one of the above mentioned request headers. /// </summary> /// <param name="description">description about the request uri.</param> /// <returns>true if If-Match or If-None-Match are allowed request headers for this request, otherwise false.</returns> internal static bool IsETagHeaderAllowed(RequestDescription description) { // IfMatch and IfNone match request headers are allowed and etag response header must be written // only when the request targets a single resource, which does not have $count and $links segment and there are no $expands query option specified. return description.IsSingleResult && description.CountOption != RequestQueryCountOption.ValueOnly && (description.RootProjectionNode == null || !description.RootProjectionNode.ExpansionsSpecified) && !description.LinkUri; }
internal static void SetStreamPropertyValue(object resourceToBeModified, Stream requestStream, IDataService service, System.Data.Services.RequestDescription description) { resourceToBeModified = service.Updatable.ResolveResource(resourceToBeModified); ResourceType resourceType = service.Provider.GetResourceType(resourceToBeModified); if (((description.TargetKind == RequestTargetKind.MediaResource) && !System.Data.Services.RequestDescription.IsNamedStream(description)) && !resourceType.IsMediaLinkEntry) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_InvalidUriForMediaResource(service.OperationContext.AbsoluteRequestUri)); } if (service.OperationContext.Host.HttpVerb == HttpVerbs.MERGE) { throw DataServiceException.CreateMethodNotAllowed(System.Data.Services.Strings.BadRequest_InvalidUriForMergeOperation(service.OperationContext.AbsoluteRequestUri), DataServiceConfiguration.GetAllowedMethods(service.Configuration, description)); } if (service.OperationContext.Host.HttpVerb == HttpVerbs.PATCH) { throw DataServiceException.CreateMethodNotAllowed(System.Data.Services.Strings.BadRequest_InvalidUriForPatchOperation(service.OperationContext.AbsoluteRequestUri), DataServiceConfiguration.GetAllowedMethods(service.Configuration, description)); } ResourceProperty streamProperty = null; if (description.TargetKind == RequestTargetKind.MediaResource) { streamProperty = System.Data.Services.RequestDescription.GetStreamProperty(description); } using (Stream stream = service.StreamProvider.GetWriteStream(resourceToBeModified, streamProperty, service.OperationContext)) { WebUtil.CopyStream(requestStream, stream, service.StreamProvider.StreamBufferSize); } }
internal static RequestDescription CreateSingleResultRequestDescription(RequestDescription description, object entity) { SegmentInfo info = new SegmentInfo { RequestExpression = Expression.Constant(entity), RequestEnumerable = new object[] { entity }, TargetKind = description.TargetKind, TargetSource = description.TargetSource, SingleResult = true, ProjectedProperty = description.Property, TargetResourceType = description.TargetResourceType, TargetContainer = description.LastSegmentInfo.TargetContainer, Identifier = description.LastSegmentInfo.Identifier }; SegmentInfo[] segmentInfos = description.SegmentInfos; segmentInfos[segmentInfos.Length - 1] = info; return new RequestDescription(segmentInfos, description.ResultUri) { responseVersion = description.ResponseVersion, actualResponseVersion = description.ActualResponseVersion, PreferenceApplied = description.PreferenceApplied }; }
internal static object CreateMediaLinkEntry(string fullTypeName, Stream requestStream, IDataService service, System.Data.Services.RequestDescription description, UpdateTracker tracker) { object target = service.Updatable.CreateResource(description.LastSegmentInfo.TargetContainer.Name, fullTypeName); tracker.TrackAction(target, description.LastSegmentInfo.TargetContainer, UpdateOperations.Add); SetStreamPropertyValue(target, requestStream, service, description); return(target); }
internal MediaResourceDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription) : base(update, dataService, tracker, requestDescription) { }
/// <summary> /// Gets a string representation of allowed methods on the container (with the specified target cardinality), /// suitable for an 'Allow' header. /// </summary> /// <param name="configuration">configuration object which has the data</param> /// <param name="container">Targetted container, possibly null.</param> /// <param name="description">Description with target.</param> /// <returns>A value for an 'Allow' header; null if <paramref name="container"/> is null.</returns> internal static string GetAllowedMethods(DataServiceConfiguration configuration, ResourceSetWrapper container, RequestDescription description) { if (container == null) { return null; } else { System.Text.StringBuilder result = new System.Text.StringBuilder(); EntitySetRights rights = configuration.GetResourceSetRights(container.ResourceSet); if (description.IsSingleResult) { AppendRight(rights, EntitySetRights.ReadSingle, XmlConstants.HttpMethodGet, result); AppendRight(rights, EntitySetRights.WriteReplace, XmlConstants.HttpMethodPut, result); if (description.TargetKind != RequestTargetKind.MediaResource) { AppendRight(rights, EntitySetRights.WriteMerge, XmlConstants.HttpMethodMerge, result); AppendRight(rights, EntitySetRights.WriteDelete, XmlConstants.HttpMethodDelete, result); } } else { AppendRight(rights, EntitySetRights.ReadMultiple, XmlConstants.HttpMethodGet, result); AppendRight(rights, EntitySetRights.WriteAppend, XmlConstants.HttpMethodPost, result); } return result.ToString(); } }
internal static bool IsETagHeaderAllowed(RequestDescription description) { if ((!description.IsSingleResult || (description.CountOption == RequestQueryCountOption.ValueOnly)) || ((description.RootProjectionNode != null) && description.RootProjectionNode.ExpansionsSpecified)) { return false; } return !description.LinkUri; }
internal static RequestDescription ProcessRequestUri(Uri absoluteRequestUri, IDataService service, bool internalQuery) { RequestDescription description; string[] segments = EnumerateSegments(absoluteRequestUri, service.OperationContext.AbsoluteServiceUri); if (segments.Length > 100) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestUriProcessor_TooManySegments); } System.Data.Services.SegmentInfo[] segmentInfos = CreateSegments(segments, service); System.Data.Services.SegmentInfo info = (segmentInfos.Length == 0) ? null : segmentInfos[segmentInfos.Length - 1]; RequestTargetKind targetKind = (info == null) ? RequestTargetKind.ServiceDirectory : info.TargetKind; Uri resultUri = GetResultUri(service.OperationContext); switch (targetKind) { case RequestTargetKind.Metadata: case RequestTargetKind.Batch: case RequestTargetKind.ServiceDirectory: description = new RequestDescription(targetKind, RequestTargetSource.None, resultUri); break; default: { RequestQueryCountOption option = (info.Identifier == "$count") ? RequestQueryCountOption.ValueOnly : RequestQueryCountOption.None; if ((option != RequestQueryCountOption.None) && !service.Configuration.DataServiceBehavior.AcceptCountRequests) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.DataServiceConfiguration_CountNotAccepted); } description = new RequestDescription(segmentInfos, resultUri) { CountOption = option }; if (!internalQuery) { description.UpdateAndCheckEpmFeatureVersion(service); description.UpdateVersions(service.OperationContext.Host.RequestAccept, service); } if (((description.TargetKind == RequestTargetKind.MediaResource) && RequestDescription.IsNamedStream(description)) && ((service.OperationContext.Host.HttpVerb != HttpVerbs.GET) && (service.OperationContext.Host.HttpVerb != HttpVerbs.PUT))) { throw DataServiceException.CreateMethodNotAllowed(System.Data.Services.Strings.RequestUriProcessor_InvalidHttpMethodForNamedStream(CommonUtil.UriToString(service.OperationContext.AbsoluteRequestUri), service.OperationContext.RequestMethod), DataServiceConfiguration.GetAllowedMethods(service.Configuration, description)); } break; } } description = RequestQueryProcessor.ProcessQuery(service, description); if (!internalQuery) { description.ApplyRequestMinVersion(service); description.AnalyzeClientPreference(service); if (description.PreferenceApplied != PreferenceApplied.None) { description.VerifyAndRaiseResponseVersion(RequestDescription.Version3Dot0, service); } } InvokeRequestExpression(description, service); return description; }
/// <summary> /// Validates that the versions of features used in the request are less then or equal than the configured /// MaxProtocolVersion. /// </summary> /// <param name="requestDescription">Request description</param> internal void ValidateMaxProtocolVersion(RequestDescription requestDescription) { Debug.Assert( Enum.GetValues(typeof(DataServiceProtocolVersion)).Length == 2, "This method has to be modified when adding/removing DataServiceProtocolVersion values."); Version maxProtocolVersion = new Version(this.DataServiceBehavior.MaxProtocolVersion == DataServiceProtocolVersion.V1 ? 1 : 2, 0); if (requestDescription.MaxFeatureVersion > maxProtocolVersion) { throw DataServiceException.CreateBadRequestError(Strings.DataServiceConfiguration_V2ResponseForV1Server); } // As a cross check let's verify if the version of the response is not higher than the configured max protocol version. Debug.Assert(maxProtocolVersion >= requestDescription.ResponseVersion, "ResponseVersion > MaxProtocolVersion"); }