Set trace id in ProblemDetalsClientErrorFactory
This commit is contained in:
parent
b649133eec
commit
82a01a414d
|
|
@ -2,12 +2,14 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
{
|
{
|
||||||
internal class ProblemDetailsClientErrorFactory : IClientErrorFactory
|
internal class ProblemDetailsClientErrorFactory : IClientErrorFactory
|
||||||
{
|
{
|
||||||
|
private static readonly string TraceIdentifierKey = "traceId";
|
||||||
private readonly ApiBehaviorOptions _options;
|
private readonly ApiBehaviorOptions _options;
|
||||||
|
|
||||||
public ProblemDetailsClientErrorFactory(IOptions<ApiBehaviorOptions> options)
|
public ProblemDetailsClientErrorFactory(IOptions<ApiBehaviorOptions> options)
|
||||||
|
|
@ -28,6 +30,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
{
|
{
|
||||||
problemDetails.Title = errorData.Title;
|
problemDetails.Title = errorData.Title;
|
||||||
problemDetails.Type = errorData.Link;
|
problemDetails.Type = errorData.Link;
|
||||||
|
|
||||||
|
SetTraceId(actionContext, problemDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ObjectResult(problemDetails)
|
return new ObjectResult(problemDetails)
|
||||||
|
|
@ -40,5 +44,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void SetTraceId(ActionContext actionContext, ProblemDetails problemDetails)
|
||||||
|
{
|
||||||
|
var traceId = Activity.Current?.Id ?? actionContext.HttpContext.TraceIdentifier;
|
||||||
|
problemDetails.Extensions[TraceIdentifierKey] = traceId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Core;
|
using Microsoft.AspNetCore.Mvc.Core;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
@ -128,9 +129,16 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IActionResult ProblemDetailsInvalidModelStateResponse(ActionContext context)
|
internal static IActionResult ProblemDetailsInvalidModelStateResponse(ActionContext context)
|
||||||
{
|
{
|
||||||
var result = new BadRequestObjectResult(new ValidationProblemDetails(context.ModelState));
|
var problemDetails = new ValidationProblemDetails(context.ModelState)
|
||||||
|
{
|
||||||
|
Status = StatusCodes.Status400BadRequest,
|
||||||
|
};
|
||||||
|
|
||||||
|
ProblemDetailsClientErrorFactory.SetTraceId(context, problemDetails);
|
||||||
|
|
||||||
|
var result = new BadRequestObjectResult(problemDetails);
|
||||||
|
|
||||||
result.ContentTypes.Add("application/problem+json");
|
result.ContentTypes.Add("application/problem+json");
|
||||||
result.ContentTypes.Add("application/problem+xml");
|
result.ContentTypes.Add("application/problem+xml");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -22,7 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = factory.GetClientError(new ActionContext(), clientError);
|
var result = factory.GetClientError(GetActionContext(), clientError);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var objectResult = Assert.IsType<ObjectResult>(result);
|
var objectResult = Assert.IsType<ObjectResult>(result);
|
||||||
|
|
@ -49,7 +51,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = factory.GetClientError(new ActionContext(), clientError);
|
var result = factory.GetClientError(GetActionContext(), clientError);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var objectResult = Assert.IsType<ObjectResult>(result);
|
var objectResult = Assert.IsType<ObjectResult>(result);
|
||||||
|
|
@ -61,5 +63,67 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
Assert.Null(problemDetails.Detail);
|
Assert.Null(problemDetails.Detail);
|
||||||
Assert.Null(problemDetails.Instance);
|
Assert.Null(problemDetails.Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetClientError_UsesActivityId_ToSetTraceId()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
using (new ActivityReplacer())
|
||||||
|
{
|
||||||
|
var clientError = new UnsupportedMediaTypeResult();
|
||||||
|
var factory = new ProblemDetailsClientErrorFactory(Options.Create(new ApiBehaviorOptions
|
||||||
|
{
|
||||||
|
ClientErrorMapping =
|
||||||
|
{
|
||||||
|
[415] = new ClientErrorData { Link = "Some link", Title = "Summary" },
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = factory.GetClientError(GetActionContext(), clientError);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var objectResult = Assert.IsType<ObjectResult>(result);
|
||||||
|
Assert.Equal(new[] { "application/problem+json", "application/problem+xml" }, objectResult.ContentTypes);
|
||||||
|
var problemDetails = Assert.IsType<ProblemDetails>(objectResult.Value);
|
||||||
|
|
||||||
|
Assert.Equal(Activity.Current.Id, problemDetails.Extensions["traceId"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetClientError_UsesHttpContext_ToSetTraceIdIfActivityIdIsNotSet()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var clientError = new UnsupportedMediaTypeResult();
|
||||||
|
var factory = new ProblemDetailsClientErrorFactory(Options.Create(new ApiBehaviorOptions
|
||||||
|
{
|
||||||
|
ClientErrorMapping =
|
||||||
|
{
|
||||||
|
[415] = new ClientErrorData { Link = "Some link", Title = "Summary" },
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = factory.GetClientError(GetActionContext(), clientError);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var objectResult = Assert.IsType<ObjectResult>(result);
|
||||||
|
Assert.Equal(new[] { "application/problem+json", "application/problem+xml" }, objectResult.ContentTypes);
|
||||||
|
var problemDetails = Assert.IsType<ProblemDetails>(objectResult.Value);
|
||||||
|
|
||||||
|
Assert.Equal("42", problemDetails.Extensions["traceId"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ActionContext GetActionContext()
|
||||||
|
{
|
||||||
|
return new ActionContext
|
||||||
|
{
|
||||||
|
HttpContext = new DefaultHttpContext
|
||||||
|
{
|
||||||
|
TraceIdentifier = "42",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
@ -97,5 +100,64 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Same(expected, options.InvalidModelStateResponseFactory);
|
Assert.Same(expected, options.InvalidModelStateResponseFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ProblemDetailsInvalidModelStateResponse_ReturnsBadRequestWithProblemDetails()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var actionContext = new ActionContext
|
||||||
|
{
|
||||||
|
HttpContext = new DefaultHttpContext { TraceIdentifier = "42" },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = ApiBehaviorOptionsSetup.ProblemDetailsInvalidModelStateResponse(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var badRequest = Assert.IsType<BadRequestObjectResult>(result);
|
||||||
|
Assert.Equal(new[] { "application/problem+json", "application/problem+xml" }, badRequest.ContentTypes.OrderBy(c => c));
|
||||||
|
|
||||||
|
var problemDetails = Assert.IsType<ValidationProblemDetails>(badRequest.Value);
|
||||||
|
Assert.Equal(400, problemDetails.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ProblemDetailsInvalidModelStateResponse_SetsTraceId()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
using (new ActivityReplacer())
|
||||||
|
{
|
||||||
|
var actionContext = new ActionContext
|
||||||
|
{
|
||||||
|
HttpContext = new DefaultHttpContext { TraceIdentifier = "42" },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = ApiBehaviorOptionsSetup.ProblemDetailsInvalidModelStateResponse(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var badRequest = Assert.IsType<BadRequestObjectResult>(result);
|
||||||
|
var problemDetails = Assert.IsType<ValidationProblemDetails>(badRequest.Value);
|
||||||
|
Assert.Equal(Activity.Current.Id, problemDetails.Extensions["traceId"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ProblemDetailsInvalidModelStateResponse_SetsTraceIdFromRequest_IfActivityIsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var actionContext = new ActionContext
|
||||||
|
{
|
||||||
|
HttpContext = new DefaultHttpContext { TraceIdentifier = "42" },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = ApiBehaviorOptionsSetup.ProblemDetailsInvalidModelStateResponse(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var badRequest = Assert.IsType<BadRequestObjectResult>(result);
|
||||||
|
var problemDetails = Assert.IsType<ValidationProblemDetails>(badRequest.Value);
|
||||||
|
Assert.Equal("42", problemDetails.Extensions["traceId"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc
|
||||||
|
{
|
||||||
|
public class ActivityReplacer : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Activity _activity;
|
||||||
|
|
||||||
|
public ActivityReplacer()
|
||||||
|
{
|
||||||
|
_activity = new Activity("Test");
|
||||||
|
_activity.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Debug.Assert(Activity.Current == _activity);
|
||||||
|
_activity.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
|
@ -35,37 +36,48 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
public async Task ActionsReturnBadRequest_WhenModelStateIsInvalid()
|
public async Task ActionsReturnBadRequest_WhenModelStateIsInvalid()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var contactModel = new Contact
|
using (new ActivityReplacer())
|
||||||
{
|
{
|
||||||
Name = "Abc",
|
var contactModel = new Contact
|
||||||
City = "Redmond",
|
|
||||||
State = "WA",
|
|
||||||
Zip = "Invalid",
|
|
||||||
};
|
|
||||||
var contactString = JsonConvert.SerializeObject(contactModel);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await Client.PostAsJsonAsync("/contact", contactModel);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
await response.AssertStatusCodeAsync(HttpStatusCode.BadRequest);
|
|
||||||
Assert.Equal("application/problem+json", response.Content.Headers.ContentType.MediaType);
|
|
||||||
var problemDetails = JsonConvert.DeserializeObject<ValidationProblemDetails>(await response.Content.ReadAsStringAsync());
|
|
||||||
Assert.Collection(
|
|
||||||
problemDetails.Errors.OrderBy(kvp => kvp.Key),
|
|
||||||
kvp =>
|
|
||||||
{
|
{
|
||||||
Assert.Equal("Name", kvp.Key);
|
Name = "Abc",
|
||||||
var error = Assert.Single(kvp.Value);
|
City = "Redmond",
|
||||||
Assert.Equal("The field Name must be a string with a minimum length of 5 and a maximum length of 30.", error);
|
State = "WA",
|
||||||
},
|
Zip = "Invalid",
|
||||||
kvp =>
|
};
|
||||||
{
|
var contactString = JsonConvert.SerializeObject(contactModel);
|
||||||
Assert.Equal("Zip", kvp.Key);
|
|
||||||
var error = Assert.Single(kvp.Value);
|
// Act
|
||||||
Assert.Equal("The field Zip must match the regular expression '\\d{5}'.", error);
|
var response = await Client.PostAsJsonAsync("/contact", contactModel);
|
||||||
}
|
|
||||||
);
|
// Assert
|
||||||
|
await response.AssertStatusCodeAsync(HttpStatusCode.BadRequest);
|
||||||
|
Assert.Equal("application/problem+json", response.Content.Headers.ContentType.MediaType);
|
||||||
|
var problemDetails = JsonConvert.DeserializeObject<ValidationProblemDetails>(await response.Content.ReadAsStringAsync());
|
||||||
|
Assert.Collection(
|
||||||
|
problemDetails.Errors.OrderBy(kvp => kvp.Key),
|
||||||
|
kvp =>
|
||||||
|
{
|
||||||
|
Assert.Equal("Name", kvp.Key);
|
||||||
|
var error = Assert.Single(kvp.Value);
|
||||||
|
Assert.Equal("The field Name must be a string with a minimum length of 5 and a maximum length of 30.", error);
|
||||||
|
},
|
||||||
|
kvp =>
|
||||||
|
{
|
||||||
|
Assert.Equal("Zip", kvp.Key);
|
||||||
|
var error = Assert.Single(kvp.Value);
|
||||||
|
Assert.Equal("The field Zip must match the regular expression '\\d{5}'.", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.Collection(
|
||||||
|
problemDetails.Extensions,
|
||||||
|
kvp =>
|
||||||
|
{
|
||||||
|
Assert.Equal("traceId", kvp.Key);
|
||||||
|
Assert.Equal(Activity.Current.Id, kvp.Value);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -253,21 +265,31 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ClientErrorResultFilterExecutesForStatusCodeResults()
|
public async Task ClientErrorResultFilterExecutesForStatusCodeResults()
|
||||||
{
|
{
|
||||||
// Act
|
using (new ActivityReplacer())
|
||||||
var response = await Client.GetAsync("/contact/ActionReturningStatusCodeResult");
|
{
|
||||||
|
// Act
|
||||||
|
var response = await Client.GetAsync("/contact/ActionReturningStatusCodeResult");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await response.AssertStatusCodeAsync(HttpStatusCode.NotFound);
|
await response.AssertStatusCodeAsync(HttpStatusCode.NotFound);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
var problemDetails = JsonConvert.DeserializeObject<ProblemDetails>(content);
|
var problemDetails = JsonConvert.DeserializeObject<ProblemDetails>(content);
|
||||||
Assert.Equal(404, problemDetails.Status);
|
Assert.Equal(404, problemDetails.Status);
|
||||||
|
Assert.Collection(
|
||||||
|
problemDetails.Extensions,
|
||||||
|
kvp =>
|
||||||
|
{
|
||||||
|
Assert.Equal("traceId", kvp.Key);
|
||||||
|
Assert.Equal(Activity.Current.Id, kvp.Value);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task SerializingProblemDetails_IgnoresNullValuedProperties()
|
public async Task SerializingProblemDetails_IgnoresNullValuedProperties()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = new[] { "status", "title", "type" };
|
var expected = new[] { "status", "title", "traceId", "type" };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await Client.GetAsync("/contact/ActionReturningStatusCodeResult");
|
var response = await Client.GetAsync("/contact/ActionReturningStatusCodeResult");
|
||||||
|
|
@ -310,7 +332,14 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
|
|
||||||
Assert.Equal("Error", validationProblemDetails.Title);
|
Assert.Equal("Error", validationProblemDetails.Title);
|
||||||
Assert.Equal(400, validationProblemDetails.Status);
|
Assert.Equal(400, validationProblemDetails.Status);
|
||||||
Assert.Equal("27", validationProblemDetails.Extensions["tracking-id"]);
|
Assert.Collection(
|
||||||
|
validationProblemDetails.Extensions,
|
||||||
|
kvp =>
|
||||||
|
{
|
||||||
|
Assert.Equal("tracking-id", kvp.Key);
|
||||||
|
Assert.Equal("27", kvp.Value);
|
||||||
|
});
|
||||||
|
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
validationProblemDetails.Errors,
|
validationProblemDetails.Errors,
|
||||||
kvp =>
|
kvp =>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\Microsoft.AspNetCore.Mvc.Formatters.Xml.Test\XmlAssert.cs" />
|
<Compile Include="..\Microsoft.AspNetCore.Mvc.Formatters.Xml.Test\XmlAssert.cs" />
|
||||||
|
<Compile Include="..\Microsoft.AspNetCore.Mvc.Core.TestCommon\ActivityReplacer.cs" />
|
||||||
<EmbeddedResource Include="compiler\resources\**\*" />
|
<EmbeddedResource Include="compiler\resources\**\*" />
|
||||||
<None Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
|
<None Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
|
|
@ -213,15 +214,23 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
public async Task ProblemDetails_IsSerialized()
|
public async Task ProblemDetails_IsSerialized()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = @"<ProblemDetails><Status>404</Status><Title>Not Found</Title><Type>https://tools.ietf.org/html/rfc7231#section-6.5.4</Type></ProblemDetails>";
|
using (new ActivityReplacer())
|
||||||
|
{
|
||||||
|
var expected = "<ProblemDetails>" +
|
||||||
|
"<Status>404</Status>" +
|
||||||
|
"<Title>Not Found</Title>" +
|
||||||
|
"<Type>https://tools.ietf.org/html/rfc7231#section-6.5.4</Type>" +
|
||||||
|
$"<traceId>{Activity.Current.Id}</traceId>" +
|
||||||
|
"</ProblemDetails>";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await Client.GetAsync("/api/XmlDataContractApi/ActionReturningClientErrorStatusCodeResult");
|
var response = await Client.GetAsync("/api/XmlDataContractApi/ActionReturningClientErrorStatusCodeResult");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await response.AssertStatusCodeAsync(HttpStatusCode.NotFound);
|
await response.AssertStatusCodeAsync(HttpStatusCode.NotFound);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
XmlAssert.Equal(expected, content);
|
XmlAssert.Equal(expected, content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -244,16 +253,25 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
public async Task ValidationProblemDetails_IsSerialized()
|
public async Task ValidationProblemDetails_IsSerialized()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = @"<ValidationProblemDetails><Status>400</Status><Title>One or more validation errors occurred.</Title>
|
using (new ActivityReplacer())
|
||||||
<MVC-Errors><State>The State field is required.</State></MVC-Errors></ValidationProblemDetails>";
|
{
|
||||||
|
var expected = "<ValidationProblemDetails>" +
|
||||||
|
"<Status>400</Status>" +
|
||||||
|
"<Title>One or more validation errors occurred.</Title>" +
|
||||||
|
$"<traceId>{Activity.Current.Id}</traceId>" +
|
||||||
|
"<MVC-Errors>" +
|
||||||
|
"<State>The State field is required.</State>" +
|
||||||
|
"</MVC-Errors>" +
|
||||||
|
"</ValidationProblemDetails>";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await Client.GetAsync("/api/XmlDataContractApi/ActionReturningValidationProblem");
|
var response = await Client.GetAsync("/api/XmlDataContractApi/ActionReturningValidationProblem");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await response.AssertStatusCodeAsync(HttpStatusCode.BadRequest);
|
await response.AssertStatusCodeAsync(HttpStatusCode.BadRequest);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
XmlAssert.Equal(expected, content);
|
XmlAssert.Equal(expected, content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
|
|
@ -188,15 +189,23 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
public async Task ProblemDetails_IsSerialized()
|
public async Task ProblemDetails_IsSerialized()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = @"<ProblemDetails><Status>404</Status><Title>Not Found</Title><Type>https://tools.ietf.org/html/rfc7231#section-6.5.4</Type></ProblemDetails>";
|
using (new ActivityReplacer())
|
||||||
|
{
|
||||||
|
var expected = "<ProblemDetails>" +
|
||||||
|
"<Status>404</Status>" +
|
||||||
|
"<Title>Not Found</Title>" +
|
||||||
|
"<Type>https://tools.ietf.org/html/rfc7231#section-6.5.4</Type>" +
|
||||||
|
$"<traceId>{Activity.Current.Id}</traceId>" +
|
||||||
|
"</ProblemDetails>";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await Client.GetAsync("/api/XmlSerializerApi/ActionReturningClientErrorStatusCodeResult");
|
var response = await Client.GetAsync("/api/XmlSerializerApi/ActionReturningClientErrorStatusCodeResult");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await response.AssertStatusCodeAsync(HttpStatusCode.NotFound);
|
await response.AssertStatusCodeAsync(HttpStatusCode.NotFound);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
XmlAssert.Equal(expected, content);
|
XmlAssert.Equal(expected, content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -219,16 +228,25 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
public async Task ValidationProblemDetails_IsSerialized()
|
public async Task ValidationProblemDetails_IsSerialized()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = @"<ValidationProblemDetails><Status>400</Status><Title>One or more validation errors occurred.</Title>
|
using (new ActivityReplacer())
|
||||||
<MVC-Errors><State>The State field is required.</State></MVC-Errors></ValidationProblemDetails>";
|
{
|
||||||
|
var expected = "<ValidationProblemDetails>" +
|
||||||
|
"<Status>400</Status>" +
|
||||||
|
"<Title>One or more validation errors occurred.</Title>" +
|
||||||
|
$"<traceId>{Activity.Current.Id}</traceId>" +
|
||||||
|
"<MVC-Errors>" +
|
||||||
|
"<State>The State field is required.</State>" +
|
||||||
|
"</MVC-Errors>" +
|
||||||
|
"</ValidationProblemDetails>";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await Client.GetAsync("/api/XmlSerializerApi/ActionReturningValidationProblem");
|
var response = await Client.GetAsync("/api/XmlSerializerApi/ActionReturningValidationProblem");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await response.AssertStatusCodeAsync(HttpStatusCode.BadRequest);
|
await response.AssertStatusCodeAsync(HttpStatusCode.BadRequest);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
XmlAssert.Equal(expected, content);
|
XmlAssert.Equal(expected, content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue