Fix for item #1278 - Add WebAPI ActionResult types and helper methods on
ApiController Ports all of the WebAPI action result types.
This commit is contained in:
parent
8966680075
commit
9fadcf74ca
|
|
@ -1,9 +1,6 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that returns a <see cref="System.Net.HttpStatusCode.BadRequest"/> response and performs
|
||||
/// content negotiation on an <see cref="HttpError"/> with a <see cref="HttpError.Message"/>.
|
||||
/// </summary>
|
||||
public class BadRequestErrorMessageResult : ObjectResult
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="BadRequestErrorMessageResult"/> class.</summary>
|
||||
/// <param name="message">The user-visible error message.</param>
|
||||
public BadRequestErrorMessageResult([NotNull] string message)
|
||||
: base(new HttpError(message))
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the error message.
|
||||
/// </summary>
|
||||
public string Message { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task ExecuteResultAsync(ActionContext context)
|
||||
{
|
||||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
await base.ExecuteResultAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that returns an empty <see cref="HttpStatusCode.BadRequest"/> response.
|
||||
/// </summary>
|
||||
public class BadRequestResult : HttpStatusCodeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BadRequestResult"/> class.
|
||||
/// </summary>
|
||||
public BadRequestResult()
|
||||
: base((int)HttpStatusCode.BadRequest)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that returns an empty <see cref="HttpStatusCode.Conflict"/> response.
|
||||
/// </summary>
|
||||
public class ConflictResult : HttpStatusCodeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConflictResult"/> class.
|
||||
/// </summary>
|
||||
public ConflictResult()
|
||||
: base((int)HttpStatusCode.Conflict)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using ShimResources = Microsoft.AspNet.Mvc.WebApiCompatShim.Resources;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an action result that performs route generation and content negotiation and returns a
|
||||
/// <see cref="HttpStatusCode.Created"/> response when content negotiation succeeds.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
public class CreatedAtRouteNegotiatedContentResult<T> : NegotiatedContentResult<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreatedAtRouteNegotiatedContentResult{T}"/> class with the
|
||||
/// values provided.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to use for generating the URL.</param>
|
||||
/// <param name="routeValues">The route data to use for generating the URL.</param>
|
||||
/// <param name="content">The content value to negotiate and format in the entity body.</param>
|
||||
/// <param name="formatters">The formatters to use to negotiate and format the content.</param>
|
||||
public CreatedAtRouteNegotiatedContentResult(
|
||||
[NotNull] string routeName,
|
||||
[NotNull] IDictionary<string, object> routeValues,
|
||||
[NotNull] T content)
|
||||
: base(HttpStatusCode.Created, content)
|
||||
{
|
||||
RouteName = routeName;
|
||||
RouteValues = routeValues;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the route to use for generating the URL.
|
||||
/// </summary>
|
||||
public string RouteName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the route data to use for generating the URL.
|
||||
/// </summary>
|
||||
public IDictionary<string, object> RouteValues { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task ExecuteResultAsync(ActionContext context)
|
||||
{
|
||||
var request = context.HttpContext.Request;
|
||||
var urlHelper = context.HttpContext.RequestServices.GetService<IUrlHelper>();
|
||||
|
||||
var url = urlHelper.RouteUrl(RouteName, RouteValues, request.Scheme, request.Host.ToUriComponent());
|
||||
if (url == null)
|
||||
{
|
||||
throw new InvalidOperationException(ShimResources.FormatCreatedAtRoute_RouteFailed(RouteName));
|
||||
}
|
||||
|
||||
context.HttpContext.Response.Headers.Add("Location", new string[] { url });
|
||||
|
||||
return base.ExecuteResultAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an action result that performs route generation and content negotiation and returns a
|
||||
/// <see cref="HttpStatusCode.Created"/> response when content negotiation succeeds.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
public class CreatedNegotiatedContentResult<T> : NegotiatedContentResult<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreatedNegotiatedContentResult{T}"/> class with the values
|
||||
/// provided.
|
||||
/// </summary>
|
||||
/// <param name="location">The location at which the content has been created.</param>
|
||||
/// <param name="content">The content value to negotiate and format in the entity body.</param>
|
||||
public CreatedNegotiatedContentResult(Uri location, T content)
|
||||
: base(HttpStatusCode.Created, content)
|
||||
{
|
||||
Location = location;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the location at which the content has been created.
|
||||
/// </summary>
|
||||
public Uri Location { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task ExecuteResultAsync(ActionContext context)
|
||||
{
|
||||
string location;
|
||||
if (Location.IsAbsoluteUri)
|
||||
{
|
||||
location = Location.AbsoluteUri;
|
||||
}
|
||||
else
|
||||
{
|
||||
location = Location.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
|
||||
}
|
||||
|
||||
context.HttpContext.Response.Headers.Add("Location", new string[] { location });
|
||||
|
||||
return base.ExecuteResultAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that returns a <see cref="HttpStatusCode.InternalServerError"/> response and
|
||||
/// performs content negotiation on an <see cref="HttpError"/> based on an <see cref="Exception"/>.
|
||||
/// </summary>
|
||||
public class ExceptionResult : ObjectResult
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="ExceptionResult"/> class.</summary>
|
||||
/// <param name="exception">The exception to include in the error.</param>
|
||||
/// <param name="includeErrorDetail">
|
||||
/// <see langword="true"/> if the error should include exception messages; otherwise, <see langword="false"/>.
|
||||
/// </param>
|
||||
/// <param name="contentNegotiator">The content negotiator to handle content negotiation.</param>
|
||||
/// <param name="request">The request message which led to this result.</param>
|
||||
/// <param name="formatters">The formatters to use to negotiate and format the content.</param>
|
||||
public ExceptionResult(Exception exception, bool includeErrorDetail)
|
||||
: base(new HttpError(exception, includeErrorDetail))
|
||||
{
|
||||
Exception = exception;
|
||||
IncludeErrorDetail = includeErrorDetail;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the exception to include in the error.
|
||||
/// </summary>
|
||||
public Exception Exception { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the error should include exception messages.
|
||||
/// </summary>
|
||||
public bool IncludeErrorDetail { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task ExecuteResultAsync(ActionContext context)
|
||||
{
|
||||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
return base.ExecuteResultAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
[Obsolete("This interface is obsolete. Use Microsoft.AspNet.Mvc.IActionResult as a replacement.", error: true)]
|
||||
public interface IHttpActionResult { }
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that returns an empty <see cref="HttpStatusCode.InternalServerError"/> response.
|
||||
/// </summary>
|
||||
public class InternalServerErrorResult : HttpStatusCodeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InternalServerErrorResult"/> class.
|
||||
/// </summary>
|
||||
public InternalServerErrorResult()
|
||||
: base((int)HttpStatusCode.InternalServerError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that returns a <see cref="System.Net.HttpStatusCode.BadRequest"/> response and performs
|
||||
/// content negotiation on an <see cref="HttpError"/> based on a <see cref="ModelStateDictionary"/>.
|
||||
/// </summary>
|
||||
public class InvalidModelStateResult : ObjectResult
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="InvalidModelStateResult"/> class.</summary>
|
||||
/// <param name="modelState">The model state to include in the error.</param>
|
||||
/// <param name="includeErrorDetail">
|
||||
/// <see langword="true"/> if the error should include exception messages; otherwise, <see langword="false"/>.
|
||||
/// </param>
|
||||
public InvalidModelStateResult([NotNull] ModelStateDictionary modelState, bool includeErrorDetail)
|
||||
: base(new HttpError(modelState, includeErrorDetail))
|
||||
{
|
||||
ModelState = modelState;
|
||||
IncludeErrorDetail = includeErrorDetail;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model state to include in the error.
|
||||
/// </summary>
|
||||
public ModelStateDictionary ModelState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the error should include exception messages.
|
||||
/// </summary>
|
||||
public bool IncludeErrorDetail { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task ExecuteResultAsync(ActionContext context)
|
||||
{
|
||||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
await base.ExecuteResultAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
[Obsolete("This class is obsolete. Use Microsoft.AspNet.Mvc.ObjectResult as a replacement.", error: true)]
|
||||
public class JsonResult<T> { }
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that performs content negotiation.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
public class NegotiatedContentResult<T> : ObjectResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NegotiatedContentResult{T}"/> class with the values provided.
|
||||
/// </summary>
|
||||
/// <param name="statusCode">The HTTP status code for the response message.</param>
|
||||
/// <param name="content">The content value to negotiate and format in the entity body.</param>
|
||||
public NegotiatedContentResult(HttpStatusCode statusCode, T content)
|
||||
: base(content)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
Content = content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTP status code for the response message.
|
||||
/// </summary>
|
||||
public HttpStatusCode StatusCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content value to negotiate and format in the entity body.
|
||||
/// </summary>
|
||||
public T Content { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task ExecuteResultAsync(ActionContext context)
|
||||
{
|
||||
context.HttpContext.Response.StatusCode = (int)StatusCode;
|
||||
return base.ExecuteResultAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
[Obsolete("This class is obsolete. Use Microsoft.AspNet.Mvc.HttpNotFoundResult as a replacement.", error: true)]
|
||||
public class NotFoundResult
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an action result that performs content negotiation and returns an <see cref="HttpStatusCode.OK"/>
|
||||
/// response when it succeeds.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
public class OkNegotiatedContentResult<T> : NegotiatedContentResult<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OkNegotiatedContentResult{T}"/> class with the values
|
||||
/// provided.
|
||||
/// </summary>
|
||||
/// <param name="content">The content value to negotiate and format in the entity body.</param>
|
||||
/// <param name="formatters">The formatters to use to negotiate and format the content.</param>
|
||||
public OkNegotiatedContentResult([NotNull] T content)
|
||||
: base(HttpStatusCode.OK, content)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that returns an empty <see cref="HttpStatusCode.OK"/> response.
|
||||
/// </summary>
|
||||
public class OkResult : HttpStatusCodeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OkResult"/> class.
|
||||
/// </summary>
|
||||
public OkResult()
|
||||
: base((int)HttpStatusCode.OK)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// An action result that returns a specified response message.
|
||||
/// </summary>
|
||||
public class ResponseMessageResult : ObjectResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ResponseMessageResult"/> class.
|
||||
/// </summary>
|
||||
/// <param name="response">The response message.</param>
|
||||
public ResponseMessageResult([NotNull] HttpResponseMessage response)
|
||||
: base(response)
|
||||
{
|
||||
Response = response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the response message.
|
||||
/// </summary>
|
||||
public HttpResponseMessage Response { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
[Obsolete("This class is obsolete, use HttpStatusCodeResult as a replacement.", error: true)]
|
||||
public class StatusCodeResult
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,20 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.WebApiCompatShim;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Newtonsoft.Json;
|
||||
using MvcMediaTypeHeaderValue = Microsoft.AspNet.Mvc.HeaderValueAbstractions.MediaTypeHeaderValue;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
|
|
@ -19,7 +25,9 @@ namespace System.Web.Http
|
|||
{
|
||||
private HttpRequestMessage _request;
|
||||
|
||||
/// <summary>Gets the action context.</summary>
|
||||
/// <summary>
|
||||
/// Gets the action context.
|
||||
/// </summary>
|
||||
/// <remarks>The setter is intended for unit testing purposes only.</remarks>
|
||||
[Activate]
|
||||
public ActionContext ActionContext { get; set; }
|
||||
|
|
@ -46,7 +54,9 @@ namespace System.Web.Http
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets the HTTP request message.</summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP request message.
|
||||
/// </summary>
|
||||
/// <remarks>The setter is intended for unit testing purposes only.</remarks>
|
||||
public HttpRequestMessage Request
|
||||
{
|
||||
|
|
@ -65,12 +75,16 @@ namespace System.Web.Http
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets a factory used to generate URLs to other APIs.</summary>
|
||||
/// <summary>
|
||||
/// Gets a factory used to generate URLs to other APIs.
|
||||
/// </summary>
|
||||
/// <remarks>The setter is intended for unit testing purposes only.</remarks>
|
||||
[Activate]
|
||||
public IUrlHelper Url { get; set; }
|
||||
|
||||
/// <summary>Gets or sets the current principal associated with this request.</summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the current principal associated with this request.
|
||||
/// </summary>
|
||||
public IPrincipal User
|
||||
{
|
||||
get
|
||||
|
|
@ -79,6 +93,296 @@ namespace System.Web.Http
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="BadRequestResult"/> (400 Bad Request).
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="BadRequestResult"/>.</returns>
|
||||
[NonAction]
|
||||
public virtual BadRequestResult BadRequest()
|
||||
{
|
||||
return new BadRequestResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="BadRequestErrorMessageResult"/> (400 Bad Request) with the specified error message.
|
||||
/// </summary>
|
||||
/// <param name="message">The user-visible error message.</param>
|
||||
/// <returns>A <see cref="BadRequestErrorMessageResult"/> with the specified error message.</returns>
|
||||
[NonAction]
|
||||
public virtual BadRequestErrorMessageResult BadRequest([NotNull] string message)
|
||||
{
|
||||
return new BadRequestErrorMessageResult(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="InvalidModelStateResult"/> (400 Bad Request) with the specified model state.
|
||||
/// </summary>
|
||||
/// <param name="modelState">The model state to include in the error.</param>
|
||||
/// <returns>An <see cref="InvalidModelStateResult"/> with the specified model state.</returns>
|
||||
[NonAction]
|
||||
public virtual InvalidModelStateResult BadRequest([NotNull] ModelStateDictionary modelState)
|
||||
{
|
||||
return new InvalidModelStateResult(modelState, includeErrorDetail: false);
|
||||
}
|
||||
|
||||
/// <summary>Creates a <see cref="ConflictResult"/> (409 Conflict).</summary>
|
||||
/// <returns>A <see cref="ConflictResult"/>.</returns>
|
||||
[NonAction]
|
||||
public virtual ConflictResult Conflict()
|
||||
{
|
||||
return new ConflictResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="NegotiatedContentResult{T}"/> with the specified values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
/// <param name="statusCode">The HTTP status code for the response message.</param>
|
||||
/// <param name="value">The content value to negotiate and format in the entity body.</param>
|
||||
/// <returns>A <see cref="NegotiatedContentResult{T}"/> with the specified values.</returns>
|
||||
[NonAction]
|
||||
public virtual NegotiatedContentResult<T> Content<T>(HttpStatusCode statusCode, [NotNull] T value)
|
||||
{
|
||||
return new NegotiatedContentResult<T>(statusCode, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="CreatedNegotiatedContentResult{T}"/> (201 Created) with the specified values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
/// <param name="location">
|
||||
/// The location at which the content has been created. Must be a relative or absolute URL.
|
||||
/// </param>
|
||||
/// <param name="content">The content value to negotiate and format in the entity body.</param>
|
||||
/// <returns>A <see cref="CreatedNegotiatedContentResult{T}"/> with the specified values.</returns>
|
||||
[NonAction]
|
||||
public virtual CreatedNegotiatedContentResult<T> Created<T>([NotNull] string location, [NotNull] T content)
|
||||
{
|
||||
return Created<T>(new Uri(location, UriKind.RelativeOrAbsolute), content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="CreatedNegotiatedContentResult{T}"/> (201 Created) with the specified values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
/// <param name="location">The location at which the content has been created.</param>
|
||||
/// <param name="content">The content value to negotiate and format in the entity body.</param>
|
||||
/// <returns>A <see cref="CreatedNegotiatedContentResult{T}"/> with the specified values.</returns>
|
||||
[NonAction]
|
||||
public virtual CreatedNegotiatedContentResult<T> Created<T>([NotNull] Uri location, [NotNull] T content)
|
||||
{
|
||||
return new CreatedNegotiatedContentResult<T>(location, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="CreatedAtRouteNegotiatedContentResult{T}"/> (201 Created) with the specified values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
/// <param name="routeName">The name of the route to use for generating the URL.</param>
|
||||
/// <param name="routeValues">The route data to use for generating the URL.</param>
|
||||
/// <param name="content">The content value to negotiate and format in the entity body.</param>
|
||||
/// <returns>A <see cref="CreatedAtRouteNegotiatedContentResult{T}"/> with the specified values.</returns>
|
||||
[NonAction]
|
||||
public virtual CreatedAtRouteNegotiatedContentResult<T> CreatedAtRoute<T>(
|
||||
[NotNull] string routeName,
|
||||
object routeValues,
|
||||
[NotNull] T content)
|
||||
{
|
||||
var values = routeValues as IDictionary<string, object>;
|
||||
if (values == null)
|
||||
{
|
||||
values = new RouteValueDictionary(routeValues);
|
||||
}
|
||||
|
||||
return new CreatedAtRouteNegotiatedContentResult<T>(routeName, values, content);
|
||||
}
|
||||
|
||||
/// <summary
|
||||
/// >Creates an <see cref="InternalServerErrorResult"/> (500 Internal Server Error).
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="InternalServerErrorResult"/>.</returns>
|
||||
[NonAction]
|
||||
public virtual InternalServerErrorResult InternalServerError()
|
||||
{
|
||||
return new InternalServerErrorResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ExceptionResult"/> (500 Internal Server Error) with the specified exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to include in the error.</param>
|
||||
/// <returns>An <see cref="ExceptionResult"/> with the specified exception.</returns>
|
||||
[NonAction]
|
||||
public virtual ExceptionResult InternalServerError([NotNull] Exception exception)
|
||||
{
|
||||
return new ExceptionResult(exception, includeErrorDetail: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ObjectResult"/> (200 OK) with the specified value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
/// <param name="content">The content value to serialize in the entity body.</param>
|
||||
/// <returns>A <see cref="ObjectResult"/> with the specified value.</returns>
|
||||
[NonAction]
|
||||
public virtual ObjectResult Json<T>([NotNull] T content)
|
||||
{
|
||||
var result = new ObjectResult(content);
|
||||
result.ContentTypes.Add(MvcMediaTypeHeaderValue.Parse("application/json"));
|
||||
result.ContentTypes.Add(MvcMediaTypeHeaderValue.Parse("text/json"));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ObjectResult"/> (200 OK) with the specified values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
/// <param name="content">The content value to serialize in the entity body.</param>
|
||||
/// <param name="serializerSettings">The serializer settings.</param>
|
||||
/// <returns>A <see cref="ObjectResult"/> with the specified values.</returns>
|
||||
[NonAction]
|
||||
public virtual ObjectResult Json<T>([NotNull] T content, [NotNull] JsonSerializerSettings serializerSettings)
|
||||
{
|
||||
var formatter = new JsonOutputFormatter()
|
||||
{
|
||||
SerializerSettings = serializerSettings,
|
||||
};
|
||||
|
||||
var result = new ObjectResult(content);
|
||||
result.Formatters.Add(formatter);
|
||||
result.ContentTypes.Add(MvcMediaTypeHeaderValue.Parse("application/json"));
|
||||
result.ContentTypes.Add(MvcMediaTypeHeaderValue.Parse("text/json"));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="JsonResult{T}"/> (200 OK) with the specified values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
/// <param name="content">The content value to serialize in the entity body.</param>
|
||||
/// <param name="serializerSettings">The serializer settings.</param>
|
||||
/// <param name="encoding">The content encoding.</param>
|
||||
/// <returns>A <see cref="JsonResult{T}"/> with the specified values.</returns>
|
||||
[NonAction]
|
||||
public virtual ObjectResult Json<T>(
|
||||
[NotNull] T content,
|
||||
[NotNull] JsonSerializerSettings serializerSettings,
|
||||
[NotNull] Encoding encoding)
|
||||
{
|
||||
var formatter = new JsonOutputFormatter()
|
||||
{
|
||||
SerializerSettings = serializerSettings,
|
||||
};
|
||||
|
||||
formatter.SupportedEncodings.Clear();
|
||||
formatter.SupportedEncodings.Add(encoding);
|
||||
|
||||
var result = new ObjectResult(content);
|
||||
result.Formatters.Add(formatter);
|
||||
result.ContentTypes.Add(MvcMediaTypeHeaderValue.Parse("application/json"));
|
||||
result.ContentTypes.Add(MvcMediaTypeHeaderValue.Parse("text/json"));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="HttpNotFoundResult"/> (404 Not Found).
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="HttpNotFoundResult"/>.</returns>
|
||||
[NonAction]
|
||||
public virtual HttpNotFoundResult NotFound()
|
||||
{
|
||||
return new HttpNotFoundResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="OkResult"/> (200 OK).
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="OkResult"/>.</returns>
|
||||
[NonAction]
|
||||
public virtual OkResult Ok()
|
||||
{
|
||||
return new OkResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="OkNegotiatedContentResult{T}"/> (200 OK) with the specified values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content in the entity body.</typeparam>
|
||||
/// <param name="content">The content value to negotiate and format in the entity body.</param>
|
||||
/// <returns>An <see cref="OkNegotiatedContentResult{T}"/> with the specified values.</returns>
|
||||
[NonAction]
|
||||
public virtual OkNegotiatedContentResult<T> Ok<T>([NotNull] T content)
|
||||
{
|
||||
return new OkNegotiatedContentResult<T>(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="RedirectResult"/> (302 Found) with the specified value.
|
||||
/// </summary>
|
||||
/// <param name="location">The location to which to redirect.</param>
|
||||
/// <returns>A <see cref="RedirectResult"/> with the specified value.</returns>
|
||||
[NonAction]
|
||||
public virtual RedirectResult Redirect([NotNull] string location)
|
||||
{
|
||||
// This is how redirect was implemented in legacy webapi - string URIs are assumed to be absolute.
|
||||
return Redirect(new Uri(location));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="RedirectResult"/> (302 Found) with the specified value.
|
||||
/// </summary>
|
||||
/// <param name="location">The location to which to redirect.</param>
|
||||
/// <returns>A <see cref="RedirectResult"/> with the specified value.</returns>
|
||||
[NonAction]
|
||||
public virtual RedirectResult Redirect([NotNull] Uri location)
|
||||
{
|
||||
string uri;
|
||||
if (location.IsAbsoluteUri)
|
||||
{
|
||||
uri = location.AbsoluteUri;
|
||||
}
|
||||
else
|
||||
{
|
||||
uri = location.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
|
||||
}
|
||||
|
||||
return new RedirectResult(uri);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="RedirectToRouteResult"/> (302 Found) with the specified values.
|
||||
/// </summary>
|
||||
/// <param name="routeName">The name of the route to use for generating the URL.</param>
|
||||
/// <param name="routeValues">The route data to use for generating the URL.</param>
|
||||
/// <returns>A <see cref="RedirectToRouteResult"/> with the specified values.</returns>
|
||||
[NonAction]
|
||||
public virtual RedirectToRouteResult RedirectToRoute([NotNull] string routeName, [NotNull] object routeValues)
|
||||
{
|
||||
return new RedirectToRouteResult(Url, routeName, routeValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="ResponseMessageResult"/> with the specified response.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP response message.</param>
|
||||
/// <returns>A <see cref="ResponseMessageResult"/> for the specified response.</returns>
|
||||
[NonAction]
|
||||
public virtual ResponseMessageResult ResponseMessage([NotNull] HttpResponseMessage response)
|
||||
{
|
||||
return new ResponseMessageResult(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="HttpStatusCodeResult"/> with the specified status code.
|
||||
/// </summary>
|
||||
/// <param name="status">The HTTP status code for the response message</param>
|
||||
/// <returns>A <see cref="HttpStatusCodeResult"/> with the specified status code.</returns>
|
||||
[NonAction]
|
||||
public virtual HttpStatusCodeResult StatusCode(HttpStatusCode status)
|
||||
{
|
||||
return new HttpStatusCodeResult((int)status);
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -154,6 +154,22 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
|||
return GetString("HttpResponseExceptionMessage");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Failed to generate a URL using route '{0}'.
|
||||
/// </summary>
|
||||
internal static string CreatedAtRoute_RouteFailed
|
||||
{
|
||||
get { return GetString("CreatedAtRoute_RouteFailed"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Failed to generate a URL using route '{0}'.
|
||||
/// </summary>
|
||||
internal static string FormatCreatedAtRoute_RouteFailed(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("CreatedAtRoute_RouteFailed"), p0);
|
||||
}
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -144,4 +144,7 @@
|
|||
<data name="HttpResponseExceptionMessage" xml:space="preserve">
|
||||
<value>Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details.</value>
|
||||
</data>
|
||||
<data name="CreatedAtRoute_RouteFailed" xml:space="preserve">
|
||||
<value>Failed to generate a URL using route '{0}'.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -0,0 +1,381 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
public class WebApiCompatShimActionResultTest
|
||||
{
|
||||
private readonly IServiceProvider _provider = TestHelper.CreateServices(nameof(WebApiCompatShimWebSite));
|
||||
private readonly Action<IApplicationBuilder> _app = new WebApiCompatShimWebSite.Startup().Configure;
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_BadRequest()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetBadRequest");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_BadRequestMessage()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetBadRequestMessage");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
Assert.Equal("{\"Message\":\"Hello, world!\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_BadRequestModelState()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
var expected = "{\"Message\":\"The request is invalid.\",\"ModelState\":{\"product.Name\":[\"Name is required.\"]}}";
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetBadRequestModelState");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
Assert.Equal(expected, content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_Conflict()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetConflict");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_Content()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetContent");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Ambiguous, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_CreatedRelative()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetCreatedRelative");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_CreatedAbsolute()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetCreatedAbsolute");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("/api/Blog/ActionResult/GetUser/5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_CreatedQualified()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetCreatedQualified");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("http://localhost/api/Blog/ActionResult/5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_CreatedUri()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetCreatedUri");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("/api/Blog/ActionResult/GetUser/5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_CreatedAtRoute()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetCreatedAtRoute");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
Assert.Equal("http://localhost/api/Blog/ActionResult/GetUser/5", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_InternalServerError()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetInternalServerError");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_InternalServerErrorException()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetInternalServerErrorException");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
Assert.Equal("{\"Message\":\"An error has occurred.\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_Json()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetJson");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_JsonSettings()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
var expected =
|
||||
"{" + Environment.NewLine +
|
||||
" \"Name\": \"Test User\"" + Environment.NewLine +
|
||||
"}";
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetJsonSettings");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expected, content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_JsonSettingsEncoding()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
var expected =
|
||||
"{" + Environment.NewLine +
|
||||
" \"Name\": \"Test User\"" + Environment.NewLine +
|
||||
"}";
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetJsonSettingsEncoding");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expected, content);
|
||||
Assert.Equal("utf-32", response.Content.Headers.ContentType.CharSet);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_NotFound()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetNotFound");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_Ok()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetOk");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_OkContent()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetOkContent");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("{\"Name\":\"Test User\"}", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_RedirectString()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetRedirectString");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
|
||||
Assert.Equal("http://localhost/api/Users", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_RedirectUri()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetRedirectUri");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
|
||||
Assert.Equal("api/Blog", response.Headers.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_ResponseMessage()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetResponseMessage");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(new string[] { "Hello" }, response.Headers.GetValues("X-Test"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_StatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetStatusCode");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.PaymentRequired, response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class BadRequestErrorMessageResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task BadRequestErrorMessageResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new BadRequestErrorMessageResult("Error");
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(400, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BadRequestErrorMessageResult_WritesHttpError()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new BadRequestErrorMessageResult("Error");
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
var content = reader.ReadToEnd();
|
||||
Assert.Equal("{\"Message\":\"Error\"}", content);
|
||||
}
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
|
||||
|
||||
var formatters = new Mock<IOutputFormattersProvider>(MockBehavior.Strict);
|
||||
formatters
|
||||
.SetupGet(f => f.OutputFormatters)
|
||||
.Returns(new List<IOutputFormatter>() { new JsonOutputFormatter(), });
|
||||
|
||||
services
|
||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(formatters.Object);
|
||||
|
||||
return services.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class BadRequestResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task BadRequestResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var context = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
|
||||
var result = new BadRequestResult();
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(400, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class ConflictResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task ConflictResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var context = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
|
||||
var result = new ConflictResult();
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(409, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class CreatedAtRouteNegotiatedContentResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task CreatedAtRouteNegotiatedContentResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var urlHelper = new Mock<IUrlHelper>(MockBehavior.Strict);
|
||||
urlHelper
|
||||
.Setup(u => u.RouteUrl(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns("http://contoso.com/api/Products/5");
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices(urlHelper.Object);
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new CreatedAtRouteNegotiatedContentResult<Product>(
|
||||
"api_route",
|
||||
new RouteValueDictionary(new { controller = "Products", id = 5 }),
|
||||
new Product());
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(201, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreatedAtRouteNegotiatedContentResult_SetsLocation()
|
||||
{
|
||||
// Arrange
|
||||
var urlHelper = new Mock<IUrlHelper>(MockBehavior.Strict);
|
||||
urlHelper
|
||||
.Setup(u => u.RouteUrl(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns("http://contoso.com/api/Products/5");
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices(urlHelper.Object);
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new CreatedAtRouteNegotiatedContentResult<Product>(
|
||||
"api_route",
|
||||
new RouteValueDictionary(new { controller = "Products", id = 5 }),
|
||||
new Product());
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("http://contoso.com/api/Products/5", httpContext.Response.Headers["Location"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreatedAtRouteNegotiatedContentResult_Fails()
|
||||
{
|
||||
// Arrange
|
||||
var urlHelper = new Mock<IUrlHelper>(MockBehavior.Strict);
|
||||
urlHelper
|
||||
.Setup(u => u.RouteUrl(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns((string)null);
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices(urlHelper.Object);
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new CreatedAtRouteNegotiatedContentResult<Product>(
|
||||
"api_route",
|
||||
new RouteValueDictionary(new { controller = "Products", id = 5 }),
|
||||
new Product());
|
||||
|
||||
// Act
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await result.ExecuteResultAsync(context));
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Failed to generate a URL using route 'api_route'.", ex.Message);
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices(IUrlHelper urlHelper)
|
||||
{
|
||||
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
|
||||
|
||||
services
|
||||
.Setup(s => s.GetService(typeof(IUrlHelper)))
|
||||
.Returns(urlHelper);
|
||||
|
||||
var formatters = new Mock<IOutputFormattersProvider>(MockBehavior.Strict);
|
||||
formatters
|
||||
.SetupGet(f => f.OutputFormatters)
|
||||
.Returns(new List<IOutputFormatter>() { new JsonOutputFormatter(), });
|
||||
|
||||
services
|
||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(formatters.Object);
|
||||
|
||||
return services.Object;
|
||||
}
|
||||
|
||||
private class Product
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class CreatedNegotiatedContentResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task CreatedNegotiatedContentResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var uri = new Uri("http://contoso.com");
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new CreatedNegotiatedContentResult<Product>(uri, new Product());
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(201, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreatedNegotiatedContentResult_SetsLocation_Uri()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var uri = new Uri("http://contoso.com");
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new CreatedNegotiatedContentResult<Product>(uri, new Product());
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("http://contoso.com/", httpContext.Response.Headers["Location"]);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://contoso.com/Api/Products")]
|
||||
[InlineData("/Api/Products")]
|
||||
[InlineData("Products")]
|
||||
public async Task CreatedNegotiatedContentResult_SetsLocation_String(string uri)
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new CreatedNegotiatedContentResult<Product>(
|
||||
new Uri(uri, UriKind.RelativeOrAbsolute),
|
||||
new Product());
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(uri, httpContext.Response.Headers["Location"]);
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
|
||||
|
||||
var formatters = new Mock<IOutputFormattersProvider>(MockBehavior.Strict);
|
||||
formatters
|
||||
.SetupGet(f => f.OutputFormatters)
|
||||
.Returns(new List<IOutputFormatter>() { new JsonOutputFormatter(), });
|
||||
|
||||
services
|
||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(formatters.Object);
|
||||
|
||||
return services.Object;
|
||||
}
|
||||
|
||||
private class Product
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class ExceptionResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task ExceptionResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new ExceptionResult(new Exception("hello, world!"), includeErrorDetail: false);
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(500, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExceptionResult_WritesHttpError()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new ExceptionResult(new Exception("hello, world!"), includeErrorDetail: false);
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
var content = reader.ReadToEnd();
|
||||
Assert.Equal("{\"Message\":\"An error has occurred.\"}", content);
|
||||
}
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
|
||||
|
||||
var formatters = new Mock<IOutputFormattersProvider>(MockBehavior.Strict);
|
||||
formatters
|
||||
.SetupGet(f => f.OutputFormatters)
|
||||
.Returns(new List<IOutputFormatter>() { new JsonOutputFormatter(), });
|
||||
|
||||
services
|
||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(formatters.Object);
|
||||
|
||||
return services.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class InternalServerErrorResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task InternalServerErrorResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var context = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
|
||||
var result = new InternalServerErrorResult();
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(500, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class InvalidModelStateResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task InvalidModelStateResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
|
||||
var modelState = new ModelStateDictionary();
|
||||
modelState.AddModelError("product.Name", "Name is required.");
|
||||
|
||||
var result = new InvalidModelStateResult(modelState, includeErrorDetail: false);
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(400, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvalidModelStateResult_WritesHttpError()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
|
||||
var modelState = new ModelStateDictionary();
|
||||
modelState.AddModelError("product.Name", "Name is required.");
|
||||
|
||||
var expected =
|
||||
"{\"Message\":\"The request is invalid.\"," +
|
||||
"\"ModelState\":{\"product.Name\":[\"Name is required.\"]}}";
|
||||
|
||||
var result = new InvalidModelStateResult(modelState, includeErrorDetail: false);
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
var content = reader.ReadToEnd();
|
||||
Assert.Equal(expected, content);
|
||||
}
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
|
||||
|
||||
var formatters = new Mock<IOutputFormattersProvider>(MockBehavior.Strict);
|
||||
formatters
|
||||
.SetupGet(f => f.OutputFormatters)
|
||||
.Returns(new List<IOutputFormatter>() { new JsonOutputFormatter(), });
|
||||
|
||||
services
|
||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(formatters.Object);
|
||||
|
||||
return services.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class NegotiatedContentResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task NegotiatedContentResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new NegotiatedContentResult<Product>(HttpStatusCode.Ambiguous, new Product());
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(300, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task NegotiatedContentResult_WritesHttpError()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new NegotiatedContentResult<Product>(HttpStatusCode.Ambiguous, new Product());
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
var content = reader.ReadToEnd();
|
||||
Assert.Equal("{\"Id\":0,\"Name\":null}", content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
|
||||
|
||||
var formatters = new Mock<IOutputFormattersProvider>(MockBehavior.Strict);
|
||||
formatters
|
||||
.SetupGet(f => f.OutputFormatters)
|
||||
.Returns(new List<IOutputFormatter>() { new JsonOutputFormatter(), });
|
||||
|
||||
services
|
||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(formatters.Object);
|
||||
|
||||
return services.Object;
|
||||
}
|
||||
|
||||
private class Product
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class OkNegotiatedContentResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task OkNegotiatedContentResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = CreateServices();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
httpContext.Response.Body = stream;
|
||||
|
||||
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
|
||||
var result = new OkNegotiatedContentResult<Product>(new Product());
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(200, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
|
||||
|
||||
var formatters = new Mock<IOutputFormattersProvider>(MockBehavior.Strict);
|
||||
formatters
|
||||
.SetupGet(f => f.OutputFormatters)
|
||||
.Returns(new List<IOutputFormatter>() { new JsonOutputFormatter(), });
|
||||
|
||||
services
|
||||
.Setup(s => s.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(formatters.Object);
|
||||
|
||||
return services.Object;
|
||||
}
|
||||
|
||||
private class Product
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
public class OkResultTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task OkResult_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var context = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
|
||||
var result = new OkResult();
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(200, context.HttpContext.Response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,15 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Web.Http
|
||||
|
|
@ -44,6 +49,385 @@ namespace System.Web.Http
|
|||
Assert.Null(controller.User);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_BadRequest()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.BadRequest();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(400, Assert.IsType<BadRequestResult>(result).StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_BadRequest_Message()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.BadRequest("Error");
|
||||
|
||||
// Assert
|
||||
var badRequest = Assert.IsType<BadRequestErrorMessageResult>(result);
|
||||
Assert.Equal("Error", badRequest.Message);
|
||||
|
||||
var httpError = Assert.IsType<HttpError>(badRequest.Value);
|
||||
Assert.Equal("Error", httpError.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_BadRequest_ModelState()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var modelState = new ModelStateDictionary();
|
||||
modelState.AddModelError("product.Name", "Name is required");
|
||||
|
||||
// Act
|
||||
var result = controller.BadRequest(modelState);
|
||||
|
||||
// Assert
|
||||
var badRequest = Assert.IsType<InvalidModelStateResult>(result);
|
||||
|
||||
var modelError = Assert.IsType<HttpError>(badRequest.Value).ModelState;
|
||||
Assert.Equal(new string[] { "Name is required" }, modelError["product.Name"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Created_Uri()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var uri = new Uri("http://contoso.com");
|
||||
var product = new Product();
|
||||
|
||||
// Act
|
||||
var result = controller.Created(uri, product);
|
||||
|
||||
// Assert
|
||||
var created = Assert.IsType<CreatedNegotiatedContentResult<Product>>(result);
|
||||
Assert.Same(product, created.Content);
|
||||
Assert.Same(uri, created.Location);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://contoso.com/Api/Products")]
|
||||
[InlineData("/Api/Products")]
|
||||
[InlineData("Products")]
|
||||
public void ApiController_Created_String(string uri)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var product = new Product();
|
||||
|
||||
// Act
|
||||
var result = controller.Created(uri, product);
|
||||
|
||||
// Assert
|
||||
var created = Assert.IsType<CreatedNegotiatedContentResult<Product>>(result);
|
||||
Assert.Same(product, created.Content);
|
||||
Assert.Equal(uri, created.Location.OriginalString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_CreatedAtRoute()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var product = new Product();
|
||||
|
||||
// Act
|
||||
var result = controller.CreatedAtRoute("api_route", new { controller = "Products" }, product);
|
||||
|
||||
// Assert
|
||||
var created = Assert.IsType<CreatedAtRouteNegotiatedContentResult<Product>>(result);
|
||||
Assert.Same(product, created.Content);
|
||||
Assert.Equal("api_route", created.RouteName);
|
||||
Assert.Equal("Products", created.RouteValues["controller"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_CreatedAtRoute_Dictionary()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var product = new Product();
|
||||
var values = new RouteValueDictionary(new { controller = "Products" });
|
||||
|
||||
// Act
|
||||
var result = controller.CreatedAtRoute("api_route", values, product);
|
||||
|
||||
// Assert
|
||||
var created = Assert.IsType<CreatedAtRouteNegotiatedContentResult<Product>>(result);
|
||||
Assert.Same(product, created.Content);
|
||||
Assert.Equal("api_route", created.RouteName);
|
||||
Assert.Equal("Products", created.RouteValues["controller"]);
|
||||
Assert.Same(values, created.RouteValues);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Conflict()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.Conflict();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(409, Assert.IsType<ConflictResult>(result).StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Content()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var content = new Product();
|
||||
|
||||
// Act
|
||||
var result = controller.Content(HttpStatusCode.Found, content);
|
||||
|
||||
// Assert
|
||||
var contentResult = Assert.IsType<NegotiatedContentResult<Product>>(result);
|
||||
Assert.Equal(HttpStatusCode.Found, contentResult.StatusCode);
|
||||
Assert.Equal(content, contentResult.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_InternalServerError()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.InternalServerError();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(500, Assert.IsType<InternalServerErrorResult>(result).StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_InternalServerError_Exception()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
var exception = new ArgumentException();
|
||||
|
||||
// Act
|
||||
var result = controller.InternalServerError(exception);
|
||||
|
||||
// Assert
|
||||
var exceptionResult = Assert.IsType<ExceptionResult>(result);
|
||||
Assert.Same(exception, exceptionResult.Exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Json()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
var product = new Product();
|
||||
|
||||
// Act
|
||||
var result = controller.Json(product);
|
||||
|
||||
// Assert
|
||||
var objectResult = Assert.IsType<ObjectResult>(result);
|
||||
Assert.Same(product, objectResult.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Json_Settings()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
var product = new Product();
|
||||
var settings = new JsonSerializerSettings();
|
||||
|
||||
// Act
|
||||
var result = controller.Json(product, settings);
|
||||
|
||||
// Assert
|
||||
var objectResult = Assert.IsType<ObjectResult>(result);
|
||||
Assert.Same(product, objectResult.Value);
|
||||
|
||||
var formatter = Assert.IsType<JsonOutputFormatter>(Assert.Single(objectResult.Formatters));
|
||||
Assert.Same(settings, formatter.SerializerSettings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Json_Settings_Encoding()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
var product = new Product();
|
||||
var settings = new JsonSerializerSettings();
|
||||
|
||||
// Act
|
||||
var result = controller.Json(product, settings, Encoding.UTF8);
|
||||
|
||||
// Assert
|
||||
var objectResult = Assert.IsType<ObjectResult>(result);
|
||||
Assert.Same(product, objectResult.Value);
|
||||
|
||||
var formatter = Assert.IsType<JsonOutputFormatter>(Assert.Single(objectResult.Formatters));
|
||||
Assert.Same(settings, formatter.SerializerSettings);
|
||||
Assert.Same(Encoding.UTF8, Assert.Single(formatter.SupportedEncodings));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_NotFound()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.NotFound();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(404, Assert.IsType<HttpNotFoundResult>(result).StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Ok()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.Ok();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(200, Assert.IsType<OkResult>(result).StatusCode);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Ok_Content()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
var product = new Product();
|
||||
|
||||
// Act
|
||||
var result = controller.Ok(product);
|
||||
|
||||
// Assert
|
||||
var okResult = Assert.IsType<OkNegotiatedContentResult<Product>>(result);
|
||||
Assert.Same(product, okResult.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_Redirect()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var uri = new Uri("http://contoso.com");
|
||||
|
||||
// Act
|
||||
var result = controller.Redirect(uri);
|
||||
|
||||
// Assert
|
||||
var redirect = Assert.IsType<RedirectResult>(result);
|
||||
Assert.Equal(uri.AbsoluteUri, result.Url);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://contoso.com/Api/Products")]
|
||||
public void ApiController_Redirect_String(string uri)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.Redirect(uri);
|
||||
|
||||
// Assert
|
||||
var redirect = Assert.IsType<RedirectResult>(result);
|
||||
Assert.Equal(uri, result.Url);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_RedirectToRoute()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.RedirectToRoute("api_route", new { controller = "Products" });
|
||||
|
||||
// Assert
|
||||
var created = Assert.IsType<RedirectToRouteResult>(result);
|
||||
Assert.Equal("api_route", created.RouteName);
|
||||
Assert.Equal("Products", created.RouteValues["controller"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_RedirectToRoute_Dictionary()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var product = new Product();
|
||||
var values = new RouteValueDictionary(new { controller = "Products" });
|
||||
|
||||
// Act
|
||||
var result = controller.RedirectToRoute("api_route", values);
|
||||
|
||||
// Assert
|
||||
var created = Assert.IsType<RedirectToRouteResult>(result);
|
||||
Assert.Equal("api_route", created.RouteName);
|
||||
Assert.Equal("Products", created.RouteValues["controller"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_ResponseMessage()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
var response = new HttpResponseMessage(HttpStatusCode.NoContent);
|
||||
|
||||
// Act
|
||||
var result = controller.ResponseMessage(response);
|
||||
|
||||
// Assert
|
||||
var responseResult = Assert.IsType<ResponseMessageResult>(result);
|
||||
Assert.Same(response, responseResult.Response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiController_StatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new ConcreteApiController();
|
||||
|
||||
// Act
|
||||
var result = controller.StatusCode(HttpStatusCode.ExpectationFailed);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(417, Assert.IsType<HttpStatusCodeResult>(result).StatusCode);
|
||||
}
|
||||
|
||||
private class Product
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
}
|
||||
|
||||
private class ConcreteApiController : ApiController
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. 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.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using System.Net;
|
||||
using System.Net.Http.Formatting;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text;
|
||||
|
||||
namespace WebApiCompatShimWebSite
|
||||
{
|
||||
public class ActionResultController : ApiController
|
||||
{
|
||||
public IActionResult GetBadRequest()
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
public IActionResult GetBadRequestMessage()
|
||||
{
|
||||
return BadRequest("Hello, world!");
|
||||
}
|
||||
|
||||
public IActionResult GetBadRequestModelState()
|
||||
{
|
||||
ModelState.AddModelError("product.Name", "Name is required.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
public IActionResult GetConflict()
|
||||
{
|
||||
return Conflict();
|
||||
}
|
||||
|
||||
public IActionResult GetContent()
|
||||
{
|
||||
return Content(HttpStatusCode.Ambiguous, CreateUser());
|
||||
}
|
||||
|
||||
public IActionResult GetCreatedRelative()
|
||||
{
|
||||
return Created("5", CreateUser());
|
||||
}
|
||||
|
||||
public IActionResult GetCreatedAbsolute()
|
||||
{
|
||||
return Created("/api/Blog/ActionResult/GetUser/5", CreateUser());
|
||||
}
|
||||
|
||||
public IActionResult GetCreatedQualified()
|
||||
{
|
||||
return Created("http://localhost/api/Blog/ActionResult/5", CreateUser());
|
||||
}
|
||||
|
||||
public IActionResult GetCreatedUri()
|
||||
{
|
||||
return Created(new Uri("/api/Blog/ActionResult/GetUser/5", UriKind.Relative), CreateUser());
|
||||
}
|
||||
|
||||
public IActionResult GetCreatedAtRoute()
|
||||
{
|
||||
var values = new { controller = "ActionResult", action = "GetUser", id = 5 };
|
||||
return CreatedAtRoute("named-action", values, CreateUser());
|
||||
}
|
||||
|
||||
public IActionResult GetInternalServerError()
|
||||
{
|
||||
return InternalServerError();
|
||||
}
|
||||
|
||||
public IActionResult GetInternalServerErrorException()
|
||||
{
|
||||
return InternalServerError(new Exception("Error not passed to client."));
|
||||
}
|
||||
|
||||
public IActionResult GetJson()
|
||||
{
|
||||
return Json(CreateUser());
|
||||
}
|
||||
|
||||
public IActionResult GetJsonSettings()
|
||||
{
|
||||
return Json(CreateUser(), new JsonSerializerSettings() { Formatting = Formatting.Indented });
|
||||
}
|
||||
|
||||
public IActionResult GetJsonSettingsEncoding()
|
||||
{
|
||||
return Json(
|
||||
CreateUser(),
|
||||
new JsonSerializerSettings() { Formatting = Formatting.Indented },
|
||||
Encoding.UTF32);
|
||||
}
|
||||
|
||||
public IActionResult GetNotFound()
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
public IActionResult GetOk()
|
||||
{
|
||||
return Ok();
|
||||
}
|
||||
|
||||
public IActionResult GetOkContent()
|
||||
{
|
||||
return Ok(CreateUser());
|
||||
}
|
||||
|
||||
public IActionResult GetRedirectString()
|
||||
{
|
||||
// strings must be absolute URIs
|
||||
return Redirect("http://localhost/api/Users");
|
||||
}
|
||||
|
||||
public IActionResult GetRedirectUri()
|
||||
{
|
||||
// Uris can be absolute or relative
|
||||
return Redirect(new Uri("api/Blog", UriKind.RelativeOrAbsolute));
|
||||
}
|
||||
|
||||
public IActionResult GetResponseMessage()
|
||||
{
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK);
|
||||
response.Headers.Add("X-Test", "Hello");
|
||||
|
||||
return ResponseMessage(response);
|
||||
}
|
||||
|
||||
public IActionResult GetStatusCode()
|
||||
{
|
||||
return StatusCode(HttpStatusCode.PaymentRequired);
|
||||
}
|
||||
|
||||
// Used for generating links
|
||||
public User GetUser(int id)
|
||||
{
|
||||
return CreateUser();
|
||||
}
|
||||
|
||||
private User CreateUser()
|
||||
{
|
||||
return new User()
|
||||
{
|
||||
Name = "Test User",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue