Exemplo n.º 1
0
        /// <summary>Handles an exception when processing a batch response.</summary>
        /// <param name='service'>Data service doing the processing.</param>
        /// <param name="host">host to which we need to write the exception message</param>
        /// <param name='exception'>Exception thrown.</param>
        /// <param name='writer'>Output writer for the batch.</param>
        internal static void HandleBatchProcessException(IDataService service, DataServiceHostWrapper host, Exception exception, StreamWriter writer)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(host != null, "host != null");
            Debug.Assert(exception != null, "exception != null");
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(service.Configuration != null, "service.Configuration != null");
            Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception)");

            string contentType;
            Encoding encoding;
            TryGetResponseFormatForError(host, out contentType, out encoding);

            HandleExceptionArgs args = new HandleExceptionArgs(exception, false, contentType, service.Configuration.UseVerboseErrors);
            service.InternalHandleException(args);
            host.ResponseVersion = XmlConstants.DataServiceVersion1Dot0 + ";";
            host.ProcessException(args);

            writer.Flush();
            Action<Stream> errorWriter = ProcessBenignException(exception, service);
            if (errorWriter == null)
            {
                errorWriter = CreateErrorSerializer(args, encoding);
            }

            errorWriter(writer.BaseStream);
            writer.WriteLine();
        }
Exemplo n.º 2
0
 internal void InitializeAndCacheHeaders(IDataService dataService)
 {
     this.hostWrapper = new DataServiceHostWrapper(this.hostInterface);
     this.CurrentDataService = dataService;
     if (this.hostInterface is IDataServiceHost2)
     {
         this.ResponseHeaders.Add("X-Content-Type-Options", "nosniff");
     }
 }
Exemplo n.º 3
0
 internal ODataResponseMessage(DataServiceHostWrapper host)
 {
     this.host = host;
 }
Exemplo n.º 4
0
 private static object[] ReadOperationParameters(DataServiceHostWrapper host, OperationWrapper operation)
 {
     object[] objArray = new object[operation.Parameters.Count];
     for (int i = 0; i < operation.Parameters.Count; i++)
     {
         Type instanceType = operation.Parameters[i].ParameterType.InstanceType;
         string queryStringItem = host.GetQueryStringItem(operation.Parameters[i].Name);
         Type underlyingType = Nullable.GetUnderlyingType(instanceType);
         if (string.IsNullOrEmpty(queryStringItem))
         {
             WebUtil.CheckSyntaxValid(instanceType.IsClass || (underlyingType != null));
             objArray[i] = null;
         }
         else
         {
             queryStringItem = queryStringItem.Trim();
             Type type = underlyingType ?? instanceType;
             if (WebConvert.IsKeyTypeQuoted(type))
             {
                 WebUtil.CheckSyntaxValid(WebConvert.IsKeyValueQuoted(queryStringItem));
             }
             WebUtil.CheckSyntaxValid(WebConvert.TryKeyStringToPrimitive(queryStringItem, type, out objArray[i]));
         }
     }
     return objArray;
 }
Exemplo n.º 5
0
 internal static void HandleBatchOperationError(IDataService service, DataServiceHostWrapper host, Exception exception, ODataBatchWriter batchWriter, Stream responseStream, Version defaultResponseVersion)
 {
     string str;
     Encoding encoding;
     string str2;
     Version version;
     TryGetResponseFormatForError(service, host, defaultResponseVersion, out str, out encoding, out str2, out version);
     HandleExceptionArgs args = new HandleExceptionArgs(exception, false, str2, service.Configuration.UseVerboseErrors);
     service.InternalHandleException(args);
     Action<Stream> action = null;
     if (host != null)
     {
         host.ResponseVersion = version.ToString(2) + ";";
         host.ProcessException(args);
         action = ProcessBenignException(exception, service);
     }
     if (action == null)
     {
         ODataBatchOperationResponseMessage operationResponseMessage;
         if (host != null)
         {
             operationResponseMessage = host.BatchServiceHost.GetOperationResponseMessage();
             WebUtil.SetResponseHeadersForBatchRequests(operationResponseMessage, host.BatchServiceHost);
         }
         else
         {
             operationResponseMessage = batchWriter.CreateOperationResponseMessage();
             operationResponseMessage.StatusCode = args.ResponseStatusCode;
         }
         using (ODataMessageWriter writer = ResponseBodyWriter.CreateMessageWriter(null, service, version, operationResponseMessage, str, null))
         {
             SerializeODataError(args, writer, responseStream, encoding);
         }
     }
 }
Exemplo n.º 6
0
 private static void TryGetResponseFormatForError(IDataService service, DataServiceHostWrapper host, Version defaultResponseVersion, out string contentType, out Encoding encoding, out string contentTypeWithCharsetAppended, out Version responseVersion)
 {
     if (host == null)
     {
         responseVersion = defaultResponseVersion;
         TryGetResponseFormatForError(null, null, null, out contentType, out encoding, out contentTypeWithCharsetAppended);
     }
     else
     {
         Version maxProtocolVersion = service.Configuration.DataServiceBehavior.MaxProtocolVersion.ToVersion();
         if (!TryGetMinResponseVersionForError(host, maxProtocolVersion, out responseVersion))
         {
             responseVersion = defaultResponseVersion;
         }
         TryGetResponseFormatForError(host.RequestAccept, host.RequestAcceptCharSet, responseVersion, out contentType, out encoding, out contentTypeWithCharsetAppended);
     }
 }
Exemplo n.º 7
0
 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;
 }
Exemplo n.º 8
0
 /// <summary>Gets content type and encoding information from the host if possible; defaults otherwise.</summary>
 /// <param name="host">Host to get headers from (possibly null).</param>
 /// <param name="contentType">After invocation, content type for the exception.</param>
 /// <param name="encoding">After invocation, encoding for the exception.</param>
 private static void TryGetResponseFormatForError(DataServiceHostWrapper host, out string contentType, out Encoding encoding)
 {
     TryGetResponseFormatForError(
         (host != null) ? host.RequestAccept : null,
         (host != null) ? host.RequestAcceptCharSet : null,
         out contentType,
         out encoding);
 }
 /// <summary>
 /// Creates a new instance of the host wrapper to cache the request headers and to validate the data from the host interface.
 /// </summary>
 internal void InitializeAndCacheHeaders()
 {
     Debug.Assert(this.hostInterface != null, "this.hostInterface != null");
     this.hostWrapper = new DataServiceHostWrapper(this.hostInterface);
 }
Exemplo n.º 10
0
        /// <summary>Reads the current object from the <paramref name="item"/>.</summary>
        /// <param name="segmentInfo">segmentinfo containing information about the current element that is getting processes</param>
        /// <param name="topLevel">true if the element currently pointed by the xml reader refers to a top level element</param>
        /// <param name="item">Item to read from.</param>
        /// <returns>returns the clr object with the data populated</returns>
        private object CreateObject(SegmentInfo segmentInfo, bool topLevel, SyndicationItem item)
        {
            Debug.Assert(item != null, "item != null");
            Debug.Assert(topLevel || !this.Update, "deep updates not supported");

            this.RecurseEnter();
            object result;

            // update the object count everytime you encounter a new resource
            this.CheckAndIncrementObjectCount();

            // Process the type annotation.
            ResourceType currentResourceType = this.GetResourceType(item, segmentInfo.TargetResourceType);

            if (currentResourceType.ResourceTypeKind != ResourceTypeKind.EntityType)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_OnlyEntityTypesMustBeSpecifiedInEntryElement(currentResourceType.FullName));
            }

            // We have the actual type info from the payload. Update the request/response DSV if any property is FF mapped with KeepInContent=false.
            this.UpdateAndCheckEpmRequestResponseDSV(currentResourceType, topLevel);

            // Get a resource cookie from the provider.
            ResourceSetWrapper container;

            if (segmentInfo.TargetKind == RequestTargetKind.OpenProperty)
            {
                // Open navigation properties are not supported on OpenTypes.
                throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(segmentInfo.Identifier));
            }
            else
            {
                Debug.Assert(segmentInfo.TargetKind == RequestTargetKind.Resource, "segmentInfo.TargetKind == RequestTargetKind.Resource");
                container = segmentInfo.TargetContainer;
            }

            DataServiceHostWrapper host = this.Service.OperationContext.Host;

            if (this.Update)
            {
                Debug.Assert(currentResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "only expecting entity types");

                // Only verify ETag if there is going to be some update applied (that's the idea)
                // In reality:
                //   - for normal entities (V1 compatible) - don't check ETags if there is no content element. (Same as in V1)
                //   - for V2 stuff - check ETags always as we can't tell if there's going to be something modified or not
                //       with EPM properties can be anywhere in the payload and thus even without content there still can be updates
                //       with MLE the properties are not in the content element but in their own element
                // It's hard to recognize if there's going to be update up front and so this below is an approximation
                //   which seems to be good enough. Note that if we add new ways of handling properties in the content
                //   the condition below might need to change.
                bool verifyETag =
                    topLevel &&
                    (HasContent(item) || currentResourceType.HasEntityPropertyMappings || currentResourceType.IsMediaLinkEntry);
                bool replaceResource = topLevel && host.AstoriaHttpVerb == AstoriaVerbs.PUT;

                // if its a top level resource, then it cannot be null
                result = this.GetObjectFromSegmentInfo(currentResourceType, segmentInfo, verifyETag, topLevel /*checkForNull*/, replaceResource);
                if (this.Tracker != null)
                {
                    this.Tracker.TrackAction(result, container, UpdateOperations.Change);
                }
            }
            else
            {
                if (segmentInfo.TargetKind == RequestTargetKind.Resource)
                {
                    DataServiceConfiguration.CheckResourceRights(segmentInfo.TargetContainer, EntitySetRights.WriteAppend);
                }

                result = this.Updatable.CreateResource(container.Name, currentResourceType.FullName);
                if (this.Tracker != null)
                {
                    this.Tracker.TrackAction(result, container, UpdateOperations.Add);
                }
            }

            // Process the content in the entry.
            EpmContentDeSerializer.EpmAppliedPropertyInfo propertiesApplied = new EpmContentDeSerializer.EpmAppliedPropertyInfo();
            this.ApplyProperties(item, currentResourceType, propertiesApplied, result);

            // Perform application of epm properties here
            if (currentResourceType.HasEntityPropertyMappings)
            {
                new EpmContentDeSerializer(currentResourceType, result).DeSerialize(
                    item,
                    new EpmContentDeSerializer.EpmContentDeserializerState {
                    IsUpdateOperation = this.Update, Updatable = this.Updatable, Service = this.Service, PropertiesApplied = propertiesApplied
                });
            }

            // Process the links in the entry.
            foreach (SyndicationLink link in item.Links)
            {
                string navigationPropertyName = UriUtil.GetNameFromAtomLinkRelationAttribute(link.RelationshipType);

                if (null == navigationPropertyName)
                {
                    continue;
                }

                Deserializer.CheckForBindingInPutOperations(host.AstoriaHttpVerb);
                Debug.Assert(segmentInfo.TargetContainer != null, "segmentInfo.TargetContainer != null");
                this.ApplyLink(link, segmentInfo.TargetContainer, currentResourceType, result, navigationPropertyName);
            }

            this.RecurseLeave();
            return(result);
        }