Skip to content

Commit d52c95b

Browse files
authored
Create ODataError in Non-Success responses (#2341)
1 parent 955ee08 commit d52c95b

File tree

12 files changed

+1017
-2
lines changed

12 files changed

+1017
-2
lines changed

src/Microsoft.AspNetCore.OData/ODataController.cs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Microsoft.AspNet.OData.Common;
55
using Microsoft.AspNet.OData.Results;
66
using Microsoft.AspNetCore.Mvc;
7+
using Microsoft.OData;
78

89
namespace Microsoft.AspNet.OData
910
{
@@ -51,5 +52,131 @@ protected virtual UpdatedODataResult<TEntity> Updated<TEntity>(TEntity entity)
5152

5253
return new UpdatedODataResult<TEntity>(entity);
5354
}
55+
56+
/// <summary>
57+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce a Bad Request (400) response.
58+
/// </summary>
59+
/// <param name="message">Error Message</param>
60+
/// <returns>A <see cref="BadRequestODataResult"/> with the specified values.</returns>
61+
protected virtual BadRequestODataResult BadRequest(string message)
62+
{
63+
return new BadRequestODataResult(message);
64+
}
65+
66+
/// <summary>
67+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce a Bad Request (400) response.
68+
/// </summary>
69+
/// <param name="odataError">Parameter of type <see cref="ODataError"/>.</param>
70+
/// <returns>A <see cref="BadRequestODataResult"/> with the specified values.</returns>
71+
protected virtual BadRequestODataResult BadRequest(ODataError odataError)
72+
{
73+
return new BadRequestODataResult(odataError);
74+
}
75+
76+
/// <summary>
77+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce a Not Found (404) response.
78+
/// </summary>
79+
/// <param name="message">Error Message</param>
80+
/// <returns>A <see cref="NotFoundODataResult"/> with the specified values.</returns>
81+
protected virtual NotFoundODataResult NotFound(string message)
82+
{
83+
return new NotFoundODataResult(message);
84+
}
85+
86+
/// <summary>
87+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce a Not Found (404) response.
88+
/// </summary>
89+
/// <param name="odataError">Parameter of type <see cref="ODataError"/>.</param>
90+
/// <returns>A <see cref="NotFoundODataResult"/> with the specified values.</returns>
91+
protected virtual NotFoundODataResult NotFound(ODataError odataError)
92+
{
93+
return new NotFoundODataResult(odataError);
94+
}
95+
96+
/// <summary>
97+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce a Unauthorized (401) response.
98+
/// </summary>
99+
/// <param name="message">Error Message</param>
100+
/// <returns>An <see cref="UnauthorizedODataResult"/> with the specified values.</returns>
101+
protected virtual UnauthorizedODataResult Unauthorized(string message)
102+
{
103+
return new UnauthorizedODataResult(message);
104+
}
105+
106+
/// <summary>
107+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce a Unauthorized (401) response.
108+
/// </summary>
109+
/// <param name="odataError">Parameter of type <see cref="ODataError"/>.</param>
110+
/// <returns>An <see cref="UnauthorizedODataResult"/> with the specified values.</returns>
111+
protected virtual UnauthorizedODataResult Unauthorized(ODataError odataError)
112+
{
113+
return new UnauthorizedODataResult(odataError);
114+
}
115+
116+
// ConflictResult and UnprocessableEntityResult were introduced in AspNet core 2.1, which is implemented from .Net standard 2.1
117+
// https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.conflict?view=aspnetcore-2.1
118+
// https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.unprocessableentityresult?view=aspnetcore-2.1
119+
#if !NETSTANDARD2_0
120+
/// <summary>
121+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce a Conflict (409) response.
122+
/// </summary>
123+
/// <param name="message">Error Message</param>
124+
/// <returns>A <see cref="ConflictODataResult"/> with the specified values.</returns>
125+
protected virtual ConflictODataResult Conflict(string message)
126+
{
127+
return new ConflictODataResult(message);
128+
}
129+
130+
/// <summary>
131+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce a Conflict (409) response.
132+
/// </summary>
133+
/// <param name="odataError">Parameter of type <see cref="ODataError"/>.</param>
134+
/// <returns>A <see cref="ConflictODataResult"/> with the specified values.</returns>
135+
protected virtual ConflictODataResult Conflict(ODataError odataError)
136+
{
137+
return new ConflictODataResult(odataError);
138+
}
139+
140+
/// <summary>
141+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce an UnprocessableEntity (422) response.
142+
/// </summary>
143+
/// <param name="message">Error Message</param>
144+
/// <returns>An <see cref="UnprocessableEntityODataResult"/> with the specified values.</returns>
145+
protected virtual UnprocessableEntityODataResult UnprocessableEntity(string message)
146+
{
147+
return new UnprocessableEntityODataResult(message);
148+
}
149+
150+
/// <summary>
151+
/// Creates a <see cref="StatusCodeResult"/> that when executed will produce an UnprocessableEntity (422) response.
152+
/// </summary>
153+
/// <param name="odataError">Parameter of type <see cref="ODataError"/>.</param>
154+
/// <returns>An <see cref="UnprocessableEntityODataResult"/> with the specified values.</returns>
155+
protected virtual UnprocessableEntityODataResult UnprocessableEntity(ODataError odataError)
156+
{
157+
return new UnprocessableEntityODataResult(odataError);
158+
}
159+
#endif
160+
161+
/// <summary>
162+
/// Creates a <see cref="ActionResult"/> that when executed will produce an <see cref="ODataError"/> response.
163+
/// </summary>
164+
/// <param name="errorCode">Http Error code.</param>
165+
/// <param name="message">Http Error Message.</param>
166+
/// <returns>An <see cref="Microsoft.AspNet.OData.Results.ODataErrorResult"/> with the specified values.</returns>
167+
protected virtual ODataErrorResult ODataErrorResult(string errorCode, string message)
168+
{
169+
return new ODataErrorResult(errorCode, message);
170+
}
171+
172+
/// <summary>
173+
/// Creates a <see cref="ActionResult"/> that when executed will produce an <see cref="ODataError"/> response.
174+
/// </summary>
175+
/// <param name="odataError"><see cref="ODataError"/>.</param>
176+
/// <returns>An <see cref="Microsoft.AspNet.OData.Results.ODataErrorResult"/> with the specified values.</returns>
177+
protected virtual ODataErrorResult ODataErrorResult(ODataError odataError)
178+
{
179+
return new ODataErrorResult(odataError);
180+
}
54181
}
55182
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Http;
6+
using Microsoft.AspNetCore.Mvc;
7+
using Microsoft.OData;
8+
9+
namespace Microsoft.AspNet.OData.Results
10+
{
11+
/// <summary>
12+
/// Represents a result that when executed will produce a Bad Request (400) response.
13+
/// </summary>
14+
/// <remarks>This result creates an <see cref="ODataError"/> with status code: 400.</remarks>
15+
public class BadRequestODataResult : BadRequestResult, IODataErrorResult
16+
{
17+
/// <summary>
18+
/// OData Error.
19+
/// </summary>
20+
public ODataError Error { get; }
21+
22+
/// <summary>
23+
/// Initializes a new instance of the class.
24+
/// </summary>
25+
/// <param name="message">Error Message</param>
26+
public BadRequestODataResult(string message)
27+
{
28+
if (message == null)
29+
{
30+
throw Common.Error.ArgumentNull("message");
31+
}
32+
33+
Error = new ODataError
34+
{
35+
Message = message,
36+
ErrorCode = "400"
37+
};
38+
}
39+
40+
/// <summary>
41+
/// Initializes a new instance of the class.
42+
/// </summary>
43+
/// <param name="odataError">OData Error.</param>
44+
public BadRequestODataResult(ODataError odataError)
45+
{
46+
if (odataError == null)
47+
{
48+
throw Common.Error.ArgumentNull("odataError");
49+
}
50+
51+
Error = odataError;
52+
}
53+
54+
/// <inheritdoc/>
55+
public async override Task ExecuteResultAsync(ActionContext context)
56+
{
57+
ObjectResult objectResult = new ObjectResult(Error)
58+
{
59+
StatusCode = StatusCodes.Status400BadRequest
60+
};
61+
62+
await objectResult.ExecuteResultAsync(context).ConfigureAwait(false);
63+
}
64+
}
65+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
#if !NETSTANDARD2_0
5+
using System.Threading.Tasks;
6+
using Microsoft.AspNetCore.Http;
7+
using Microsoft.AspNetCore.Mvc;
8+
using Microsoft.OData;
9+
10+
namespace Microsoft.AspNet.OData.Results
11+
{
12+
/// <summary>
13+
/// Represents a result that when executed will produce a Conflict (409) response.
14+
/// </summary>
15+
/// <remarks>This result creates an <see cref="ODataError"/> with status code: 409.</remarks>
16+
public class ConflictODataResult : ConflictResult, IODataErrorResult
17+
{
18+
/// <summary>
19+
/// OData Error.
20+
/// </summary>
21+
public ODataError Error { get; }
22+
23+
/// <summary>
24+
/// Initializes a new instance of the class.
25+
/// </summary>
26+
/// <param name="message">Error Message</param>
27+
public ConflictODataResult(string message)
28+
{
29+
if (message == null)
30+
{
31+
throw Common.Error.ArgumentNull("message");
32+
}
33+
34+
Error = new ODataError
35+
{
36+
Message = message,
37+
ErrorCode = "409"
38+
};
39+
}
40+
41+
/// <summary>
42+
/// Initializes a new instance of the class.
43+
/// </summary>
44+
/// <param name="odataError">OData Error.</param>
45+
public ConflictODataResult(ODataError odataError)
46+
{
47+
if (odataError == null)
48+
{
49+
throw Common.Error.ArgumentNull("odataError");
50+
}
51+
52+
Error = odataError;
53+
}
54+
55+
/// <inheritdoc/>
56+
public async override Task ExecuteResultAsync(ActionContext context)
57+
{
58+
ObjectResult objectResult = new ObjectResult(Error)
59+
{
60+
StatusCode = StatusCodes.Status409Conflict
61+
};
62+
63+
await objectResult.ExecuteResultAsync(context).ConfigureAwait(false);
64+
}
65+
}
66+
}
67+
#endif
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using Microsoft.OData;
5+
6+
namespace Microsoft.AspNet.OData.Results
7+
{
8+
/// <summary>
9+
/// Provide the interface for the details of a given OData Error result.
10+
/// </summary>
11+
public interface IODataErrorResult
12+
{
13+
/// <summary>
14+
/// OData Error.
15+
/// </summary>
16+
ODataError Error { get; }
17+
}
18+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Http;
6+
using Microsoft.AspNetCore.Mvc;
7+
using Microsoft.OData;
8+
9+
namespace Microsoft.AspNet.OData.Results
10+
{
11+
/// <summary>
12+
/// Represents a result that when executed will produce a Not Found (404) response.
13+
/// </summary>
14+
/// <remarks>This result creates an <see cref="ODataError"/> with status code: 404.</remarks>
15+
public class NotFoundODataResult : NotFoundResult, IODataErrorResult
16+
{
17+
/// <summary>
18+
/// OData Error.
19+
/// </summary>
20+
public ODataError Error { get; }
21+
22+
/// <summary>
23+
/// Initializes a new instance of the class.
24+
/// </summary>
25+
/// <param name="message">Error Message</param>
26+
public NotFoundODataResult(string message)
27+
{
28+
if (message == null)
29+
{
30+
throw Common.Error.ArgumentNull("message");
31+
}
32+
33+
Error = new ODataError
34+
{
35+
Message = message,
36+
ErrorCode = "404"
37+
};
38+
}
39+
40+
/// <summary>
41+
/// Initializes a new instance of the class.
42+
/// </summary>
43+
/// <param name="odataError">OData Error.</param>
44+
public NotFoundODataResult(ODataError odataError)
45+
{
46+
if (odataError == null)
47+
{
48+
throw Common.Error.ArgumentNull("odataError");
49+
}
50+
51+
Error = odataError;
52+
}
53+
54+
/// <inheritdoc/>
55+
public async override Task ExecuteResultAsync(ActionContext context)
56+
{
57+
ObjectResult objectResult = new ObjectResult(Error)
58+
{
59+
StatusCode = StatusCodes.Status404NotFound
60+
};
61+
62+
await objectResult.ExecuteResultAsync(context).ConfigureAwait(false);
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)