Example #1
0
        private static async Task <object> FindResource(SubmitContext context, DataModificationItem item, CancellationToken cancellationToken)
        {
            var apiBase = context.Api;
            var query   = apiBase.GetQueryableSource(item.ResourceSetName);

            query = item.ApplyTo(query);

            var result = await apiBase.QueryAsync(new QueryRequest(query), cancellationToken).ConfigureAwait(false);

            var resource = result.Results.SingleOrDefault();

            if (resource == null)
            {
                throw new StatusCodeException(HttpStatusCode.NotFound, Resources.ResourceNotFound);
            }

            // This means no If-Match or If-None-Match header
            if (item.OriginalValues == null || item.OriginalValues.Count == 0)
            {
                return(resource);
            }

            resource = item.ValidateEtag(result.Results.AsQueryable());
            return(resource);
        }
Example #2
0
        private static async Task <object> FindEntity(
            SubmitContext context,
            DataModificationItem entry,
            CancellationToken cancellationToken)
        {
            IQueryable query = context.ApiContext.GetQueryableSource(entry.ResourceSetName);

            query = entry.ApplyTo(query);

            QueryResult result = await context.ApiContext.QueryAsync(new QueryRequest(query), cancellationToken);

            object entity = result.Results.SingleOrDefault();

            if (entity == null)
            {
                // TODO GitHubIssue#38 : Handle the case when entity is resolved
                // there are 2 cases where the entity is not found:
                // 1) it doesn't exist
                // 2) concurrency checks have failed
                // we should account for both - I can see 3 options:
                // a. always return "PreConditionFailed" result
                //  - this is the canonical behavior of WebAPI OData, see the following post:
                //    "Getting started with ASP.NET Web API 2.2 for OData v4.0" on http://blogs.msdn.com/b/webdev/.
                //  - this makes sense because if someone deleted the record, then you still have a concurrency error
                // b. possibly doing a 2nd query with just the keys to see if the record still exists
                // c. only query with the keys, and then set the DbEntityEntry's OriginalValues to the ETag values,
                //    letting the save fail if there are concurrency errors

                ////throw new EntityNotFoundException
                throw new InvalidOperationException(Resources.ResourceNotFound);
            }

            return(entity);
        }
Example #3
0
        private static async Task <object> FindEntity(
            SubmitContext context,
            DataModificationItem item,
            CancellationToken cancellationToken)
        {
            IQueryable query = context.ApiContext.GetQueryableSource(item.EntitySetName);

            query = item.ApplyTo(query);

            QueryResult result = await context.ApiContext.QueryAsync(new QueryRequest(query), cancellationToken);

            object entity = result.Results.SingleOrDefault();

            if (entity == null)
            {
                throw new ResourceNotFoundException(Resources.ResourceNotFound);
            }

            // This means no If-Match or If-None-Match header
            if (item.OriginalValues == null || item.OriginalValues.Count == 0)
            {
                return(entity);
            }

            var etagEntity = item.ApplyEtag(result.Results.AsQueryable()).SingleOrDefault();

            if (etagEntity == null)
            {
                // If ETAG does not match, should return 412 Precondition Failed
                var message = string.Format(
                    CultureInfo.InvariantCulture,
                    Resources.PreconditionCheckFailed,
                    new object[] { item.DataModificationItemAction, entity });
                throw new PreconditionFailedException(message);
            }

            return(etagEntity);
        }