Skip to content

Commit

Permalink
Create ODataError for non-success responses (#623)
Browse files Browse the repository at this point in the history
  • Loading branch information
KenitoInc committed Jul 4, 2022
1 parent 9225d1e commit c4f229d
Show file tree
Hide file tree
Showing 21 changed files with 4,811 additions and 5 deletions.
8 changes: 8 additions & 0 deletions src/Microsoft.AspNetCore.OData/Common/Error.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,5 +229,13 @@ internal static NotSupportedException NotSupported(string messageFormat, params
{
return new NotSupportedException(Error.Format(messageFormat, messageArgs));
}

internal static void ValidateErrorCode(string expectedErrorCode, Microsoft.OData.ODataError error)
{
if (expectedErrorCode != error.ErrorCode)
{
throw Argument(error.ErrorCode, "Invalid error code");
}
}
}
}
252 changes: 252 additions & 0 deletions src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1132,8 +1132,26 @@ Microsoft.AspNetCore.OData.Query.Wrapper.DynamicTypeWrapper.TryGetPropertyValue(
Microsoft.AspNetCore.OData.Query.Wrapper.ISelectExpandWrapper
Microsoft.AspNetCore.OData.Query.Wrapper.ISelectExpandWrapper.ToDictionary() -> System.Collections.Generic.IDictionary<string, object>
Microsoft.AspNetCore.OData.Query.Wrapper.ISelectExpandWrapper.ToDictionary(System.Func<Microsoft.OData.Edm.IEdmModel, Microsoft.OData.Edm.IEdmStructuredType, Microsoft.AspNetCore.OData.Query.Container.IPropertyMapper> propertyMapperProvider) -> System.Collections.Generic.IDictionary<string, object>
Microsoft.AspNetCore.OData.Results.BadRequestODataResult
Microsoft.AspNetCore.OData.Results.BadRequestODataResult.BadRequestODataResult(Microsoft.OData.ODataError odataError) -> void
Microsoft.AspNetCore.OData.Results.BadRequestODataResult.BadRequestODataResult(string message) -> void
Microsoft.AspNetCore.OData.Results.BadRequestODataResult.Error.get -> Microsoft.OData.ODataError
Microsoft.AspNetCore.OData.Results.ConflictODataResult
Microsoft.AspNetCore.OData.Results.ConflictODataResult.ConflictODataResult(Microsoft.OData.ODataError odataError) -> void
Microsoft.AspNetCore.OData.Results.ConflictODataResult.ConflictODataResult(string message) -> void
Microsoft.AspNetCore.OData.Results.ConflictODataResult.Error.get -> Microsoft.OData.ODataError
Microsoft.AspNetCore.OData.Results.CreatedODataResult<T>
Microsoft.AspNetCore.OData.Results.CreatedODataResult<T>.CreatedODataResult(T entity) -> void
Microsoft.AspNetCore.OData.Results.IODataErrorResult
Microsoft.AspNetCore.OData.Results.IODataErrorResult.Error.get -> Microsoft.OData.ODataError
Microsoft.AspNetCore.OData.Results.NotFoundODataResult
Microsoft.AspNetCore.OData.Results.NotFoundODataResult.Error.get -> Microsoft.OData.ODataError
Microsoft.AspNetCore.OData.Results.NotFoundODataResult.NotFoundODataResult(Microsoft.OData.ODataError odataError) -> void
Microsoft.AspNetCore.OData.Results.NotFoundODataResult.NotFoundODataResult(string message) -> void
Microsoft.AspNetCore.OData.Results.ODataErrorResult
Microsoft.AspNetCore.OData.Results.ODataErrorResult.Error.get -> Microsoft.OData.ODataError
Microsoft.AspNetCore.OData.Results.ODataErrorResult.ODataErrorResult(Microsoft.OData.ODataError odataError) -> void
Microsoft.AspNetCore.OData.Results.ODataErrorResult.ODataErrorResult(string errorCode, string message) -> void
Microsoft.AspNetCore.OData.Results.PageResult
Microsoft.AspNetCore.OData.Results.PageResult.Count.get -> long?
Microsoft.AspNetCore.OData.Results.PageResult.NextPageLink.get -> System.Uri
Expand All @@ -1148,6 +1166,14 @@ Microsoft.AspNetCore.OData.Results.SingleResult.SingleResult(System.Linq.IQuerya
Microsoft.AspNetCore.OData.Results.SingleResult<T>
Microsoft.AspNetCore.OData.Results.SingleResult<T>.Queryable.get -> System.Linq.IQueryable<T>
Microsoft.AspNetCore.OData.Results.SingleResult<T>.SingleResult(System.Linq.IQueryable<T> queryable) -> void
Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult
Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult.Error.get -> Microsoft.OData.ODataError
Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult.UnauthorizedODataResult(Microsoft.OData.ODataError odataError) -> void
Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult.UnauthorizedODataResult(string message) -> void
Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult
Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult.Error.get -> Microsoft.OData.ODataError
Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult.UnprocessableEntityODataResult(Microsoft.OData.ODataError odataError) -> void
Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult.UnprocessableEntityODataResult(string message) -> void
Microsoft.AspNetCore.OData.Results.UpdatedODataResult<T>
Microsoft.AspNetCore.OData.Results.UpdatedODataResult<T>.UpdatedODataResult(T entity) -> void
Microsoft.AspNetCore.OData.Routing.Attributes.ODataAttributeRoutingAttribute
Expand Down Expand Up @@ -1436,8 +1462,14 @@ override Microsoft.AspNetCore.OData.Query.ETag.TrySetMember(System.Dynamic.SetMe
override Microsoft.AspNetCore.OData.Query.ETag<TEntity>.ApplyTo(System.Linq.IQueryable query) -> System.Linq.IQueryable
override Microsoft.AspNetCore.OData.Query.ODataQueryOptions<TEntity>.ApplyTo(System.Linq.IQueryable query) -> System.Linq.IQueryable
override Microsoft.AspNetCore.OData.Query.ODataQueryOptions<TEntity>.ApplyTo(System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) -> System.Linq.IQueryable
override Microsoft.AspNetCore.OData.Results.BadRequestODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
override Microsoft.AspNetCore.OData.Results.ConflictODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
override Microsoft.AspNetCore.OData.Results.CreatedODataResult<T>.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
override Microsoft.AspNetCore.OData.Results.NotFoundODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
override Microsoft.AspNetCore.OData.Results.ODataErrorResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
override Microsoft.AspNetCore.OData.Results.PageResult<T>.ToDictionary() -> System.Collections.Generic.IDictionary<string, object>
override Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
override Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
override Microsoft.AspNetCore.OData.Results.UpdatedODataResult<T>.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
override Microsoft.AspNetCore.OData.Routing.Conventions.ActionRoutingConvention.AppliesToAction(Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) -> bool
override Microsoft.AspNetCore.OData.Routing.Conventions.ActionRoutingConvention.IsOperationParameterMatched(Microsoft.OData.Edm.IEdmOperation operation, Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) -> bool
Expand Down Expand Up @@ -1822,7 +1854,19 @@ virtual Microsoft.AspNetCore.OData.Query.Validator.SkipTokenQueryValidator.Valid
virtual Microsoft.AspNetCore.OData.Query.Validator.TopQueryValidator.Validate(Microsoft.AspNetCore.OData.Query.TopQueryOption topQueryOption, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) -> void
virtual Microsoft.AspNetCore.OData.Results.CreatedODataResult<T>.Entity.get -> T
virtual Microsoft.AspNetCore.OData.Results.UpdatedODataResult<T>.Entity.get -> T
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.BadRequest(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.BadRequestODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.BadRequest(string message) -> Microsoft.AspNetCore.OData.Results.BadRequestODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Conflict(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.ConflictODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Conflict(string message) -> Microsoft.AspNetCore.OData.Results.ConflictODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Created<TEntity>(TEntity entity) -> Microsoft.AspNetCore.OData.Results.CreatedODataResult<TEntity>
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.NotFound(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.NotFoundODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.NotFound(string message) -> Microsoft.AspNetCore.OData.Results.NotFoundODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.ODataErrorResult(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.ODataErrorResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.ODataErrorResult(string errorCode, string message) -> Microsoft.AspNetCore.OData.Results.ODataErrorResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Unauthorized(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Unauthorized(string message) -> Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.UnprocessableEntity(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.UnprocessableEntity(string message) -> Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult
virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Updated<TEntity>(TEntity entity) -> Microsoft.AspNetCore.OData.Results.UpdatedODataResult<TEntity>
virtual Microsoft.AspNetCore.OData.Routing.Conventions.AttributeRoutingConvention.AppliesToAction(Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) -> bool
virtual Microsoft.AspNetCore.OData.Routing.Conventions.AttributeRoutingConvention.AppliesToController(Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) -> bool
Expand Down
74 changes: 74 additions & 0 deletions src/Microsoft.AspNetCore.OData/Results/BadRequestODataResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
// <copyright file="BadRequestODataResult.cs" company=".NET Foundation">
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
// See License.txt in the project root for license information.
// </copyright>
//------------------------------------------------------------------------------

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OData;
using ErrorUtils = Microsoft.AspNetCore.OData.Error;

namespace Microsoft.AspNetCore.OData.Results
{
/// <summary>
/// Represents a result that when executed will produce a Bad Request (400) response.
/// </summary>
/// <remarks>This result creates an <see cref="ODataError"/> with status code: 400.</remarks>
public class BadRequestODataResult : BadRequestResult, IODataErrorResult
{
private const string errorCode = "400";

/// <summary>
/// OData error.
/// </summary>
public ODataError Error { get; }

/// <summary>
/// Initializes a new instance of the class.
/// </summary>
/// <param name="message">Error message.</param>
public BadRequestODataResult(string message)
{
if (string.IsNullOrEmpty(message))
{
throw ErrorUtils.ArgumentNullOrEmpty(nameof(message));
}

Error = new ODataError
{
Message = message,
ErrorCode = errorCode
};
}

/// <summary>
/// Initializes a new instance of the class.
/// </summary>
/// <param name="odataError">An <see cref="ODataError"/> object.</param>
public BadRequestODataResult(ODataError odataError)
{
if (odataError == null)
{
throw ErrorUtils.ArgumentNull(nameof(odataError));
}

ErrorUtils.ValidateErrorCode(errorCode, odataError);

Error = odataError;
}

/// <inheritdoc/>
public async override Task ExecuteResultAsync(ActionContext context)
{
ObjectResult objectResult = new ObjectResult(Error)
{
StatusCode = StatusCodes.Status400BadRequest
};

await objectResult.ExecuteResultAsync(context).ConfigureAwait(false);
}
}
}
74 changes: 74 additions & 0 deletions src/Microsoft.AspNetCore.OData/Results/ConflictODataResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
// <copyright file="ConflictODataResult.cs" company=".NET Foundation">
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
// See License.txt in the project root for license information.
// </copyright>
//------------------------------------------------------------------------------

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OData;
using ErrorUtils = Microsoft.AspNetCore.OData.Error;

namespace Microsoft.AspNetCore.OData.Results
{
/// <summary>
/// Represents a result that when executed will produce a Conflict (409) response.
/// </summary>
/// <remarks>This result creates an <see cref="ODataError"/> with status code: 409.</remarks>
public class ConflictODataResult : ConflictResult, IODataErrorResult
{
private const string errorCode = "409";

/// <summary>
/// OData error.
/// </summary>
public ODataError Error { get; }

/// <summary>
/// Initializes a new instance of the class.
/// </summary>
/// <param name="message">Error message.</param>
public ConflictODataResult(string message)
{
if (string.IsNullOrEmpty(message))
{
throw ErrorUtils.ArgumentNullOrEmpty(nameof(message));
}

Error = new ODataError
{
Message = message,
ErrorCode = errorCode
};
}

/// <summary>
/// Initializes a new instance of the class.
/// </summary>
/// <param name="odataError">An <see cref="ODataError"/> object.</param>
public ConflictODataResult(ODataError odataError)
{
if (odataError == null)
{
throw ErrorUtils.ArgumentNull(nameof(odataError));
}

ErrorUtils.ValidateErrorCode(errorCode, odataError);

Error = odataError;
}

/// <inheritdoc/>
public async override Task ExecuteResultAsync(ActionContext context)
{
ObjectResult objectResult = new ObjectResult(Error)
{
StatusCode = StatusCodes.Status409Conflict
};

await objectResult.ExecuteResultAsync(context).ConfigureAwait(false);
}
}
}
24 changes: 24 additions & 0 deletions src/Microsoft.AspNetCore.OData/Results/IODataErrorResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
// <copyright file="IODataErrorResult.cs" company=".NET Foundation">
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
// See License.txt in the project root for license information.
// </copyright>
//------------------------------------------------------------------------------

using Microsoft.OData;

namespace Microsoft.AspNetCore.OData.Results
{
/// <summary>
/// Provide the interface for the details of a given OData error result.
/// </summary>
public interface IODataErrorResult
{
/// <summary>
/// OData error.
/// </summary>
#pragma warning disable CA1716 // Identifiers should not match keywords
ODataError Error { get; }
#pragma warning restore CA1716 // Identifiers should not match keywords
}
}
74 changes: 74 additions & 0 deletions src/Microsoft.AspNetCore.OData/Results/NotFoundODataResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
// <copyright file="NotFoundODataResult.cs" company=".NET Foundation">
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
// See License.txt in the project root for license information.
// </copyright>
//------------------------------------------------------------------------------

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OData;
using ErrorUtils = Microsoft.AspNetCore.OData.Error;

namespace Microsoft.AspNetCore.OData.Results
{
/// <summary>
/// Represents a result that when executed will produce a Not Found (404) response.
/// </summary>
/// <remarks>This result creates an <see cref="ODataError"/> with status code: 404.</remarks>
public class NotFoundODataResult : NotFoundResult, IODataErrorResult
{
private const string errorCode = "404";

/// <summary>
/// OData error.
/// </summary>
public ODataError Error { get; }

/// <summary>
/// Initializes a new instance of the class.
/// </summary>
/// <param name="message">Error message.</param>
public NotFoundODataResult(string message)
{
if (string.IsNullOrEmpty(message))
{
throw ErrorUtils.ArgumentNullOrEmpty(nameof(message));
}

Error = new ODataError
{
Message = message,
ErrorCode = errorCode
};
}

/// <summary>
/// Initializes a new instance of the class.
/// </summary>
/// <param name="odataError">An <see cref="ODataError"/> object.</param>
public NotFoundODataResult(ODataError odataError)
{
if (odataError == null)
{
throw ErrorUtils.ArgumentNull(nameof(odataError));
}

ErrorUtils.ValidateErrorCode(errorCode, odataError);

Error = odataError;
}

/// <inheritdoc/>
public async override Task ExecuteResultAsync(ActionContext context)
{
ObjectResult objectResult = new ObjectResult(Error)
{
StatusCode = StatusCodes.Status404NotFound
};

await objectResult.ExecuteResultAsync(context).ConfigureAwait(false);
}
}
}
Loading

0 comments on commit c4f229d

Please sign in to comment.