wake-up-neo.com

Geben Sie den Inhalt mit IHttpActionResult für eine nicht OK-Antwort zurück

Für die Rückgabe von einem Web-API-2-Controller kann ich Inhalt mit der Antwort zurückgeben, wenn die Antwort in Ordnung ist (Status 200):

    public IHttpActionResult Get()
    {
        string myResult = ...
        return Ok(myResult);
    }

Wenn möglich, möchte ich die integrierten Ergebnistypen hier verwenden, wenn möglich: https://msdn.Microsoft.com/en-us/library/system.web.http.results (v=vs.118). aspx

Meine Frage ist, für eine andere Art von Antwort (nicht 200), wie kann ich eine Nachricht (Zeichenfolge) damit zurückschicken? Zum Beispiel kann ich das machen:

    public IHttpActionResult Get()
    {
       return InternalServerError();
    }

aber nicht das:

    public IHttpActionResult Get()
    {
       return InternalServerError("Message describing the error here");
    }

Im Idealfall möchte ich, dass dies verallgemeinert wird, sodass ich eine Nachricht mit einer der Implementierungen von IHttpActionResult zurücksenden kann.

Muss ich das tun (und meine eigene Antwortnachricht erstellen):

    public IHttpActionResult Get()
    {
       HttpResponseMessage responseMessage = ...
       return ResponseMessage(responseMessage);
    }

oder gibt es einen besseren Weg?

147
mayabelle

Am Ende habe ich folgende Lösung gewählt:

public class HttpActionResult : IHttpActionResult
{
    private readonly string _message;
    private readonly HttpStatusCode _statusCode;

    public HttpActionResult(HttpStatusCode statusCode, string message)
    {
        _statusCode = statusCode;
        _message = message;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = new HttpResponseMessage(_statusCode)
        {
            Content = new StringContent(_message)
        };
        return Task.FromResult(response);
    }
}

... die so verwendet werden kann:

public IHttpActionResult Get()
{
   return new HttpActionResult(HttpStatusCode.InternalServerError, "error message"); // can use any HTTP status code
}

Ich bin offen für Verbesserungsvorschläge. :)

29
mayabelle

Sie können dies verwenden:

return Content(HttpStatusCode.BadRequest, "Any object");
369
Shamil Yakupov

Sie können HttpRequestMessagesExtensions.CreateErrorResponse (System.Net.Http Namespace) wie folgt verwenden:

public IHttpActionResult Get()
{
   return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Message describing the error here"));
}

Es ist vorzuziehen, Antworten auf Basis der Anforderung zu erstellen, um die Inhaltsaushandlung von Web API zu nutzen.

49
user1620220

Sie können auch tun:

return InternalServerError(new Exception("SOME CUSTOM MESSAGE"));
15
ilans

Jeder, der daran interessiert ist, irgendetwas mit beliebigem Statuscode und ResponseMessage zurückzugeben:

//CreateResponse(HttpStatusCode, T value)
return ResponseMessage(Request.CreateResponse(HttpStatusCode.XX, object));
7
CularBytes

In ASP.NET Web API 2 können Sie jede ResponseMessage in ein ResponseMessageResult einschließen:

public IHttpActionResult Get()
{
   HttpResponseMessage responseMessage = ...
   return new ResponseMessageResult(responseMessage);
}

In einigen Fällen ist dies möglicherweise die einfachste Methode, um das gewünschte Ergebnis zu erzielen. In der Regel ist es jedoch vorzuziehen, die verschiedenen Ergebnisse in System.Web.Http.Results zu verwenden.

6
sfuqua

Einfach:

return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Your message"));

Denken Sie daran, auf System.Net.Http und System.Net zu verweisen.

4
Rodrigo Reis

Ich würde empfehlen, diesen Beitrag zu lesen. Es gibt unzählige Möglichkeiten, die vorhandene HttpResponse wie vorgeschlagen zu verwenden. Wenn Sie Web Api 2 jedoch nutzen möchten, sollten Sie einige der integrierten Optionen von IHttpActionResult verwenden, z 

return Ok() 

oder 

return NotFound()

Wählen Sie den richtigen Rückgabetyp für Web-API-Controller

1
wegunterjr

@mayabelle Sie können IHttpActionResult Beton erstellen und diesen Code wie folgt verpacken:

public class NotFoundPlainTextActionResult : IHttpActionResult
{
    public NotFoundPlainTextActionResult(HttpRequestMessage request, string message)
    {
        Request = request;
        Message = message;
    }

    public string Message { get; private set; }
    public HttpRequestMessage Request { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(ExecuteResult());
    }

    public HttpResponseMessage ExecuteResult()
    {
        var response = new HttpResponseMessage();

        if (!string.IsNullOrWhiteSpace(Message))
            //response.Content = new StringContent(Message);
            response = Request.CreateErrorResponse(HttpStatusCode.NotFound, new Exception(Message));

        response.RequestMessage = Request;
        return response;
    }
}
1
Quoc Nguyen

Ausnahmen mache ich normalerweise

 catch (Exception ex)
        {
            return InternalServerError(new ApplicationException("Something went wrong in this request. internal exception: " + ex.Message));
        }
0
ahsant

diese Antwort basiert auf der Antwort von Shamil Yakupov, mit einem realen Objekt anstelle einer Zeichenfolge.

using System.Dynamic;

dynamic response = new ExpandoObject();
response.message = "Email address already exist";

return Content<object>(HttpStatusCode.BadRequest, response);
0
Kugan Kumar

Ich hatte das gleiche Problem. Ich möchte ein benutzerdefiniertes Ergebnis für meine API-Controller erstellen, um sie wie return Ok("some text"); aufzurufen.

Dann habe ich Folgendes gemacht: 1) Erstellen Sie einen benutzerdefinierten Ergebnistyp mit Singletone

public sealed class EmptyResult : IHttpActionResult
{
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.NoContent) { Content = new StringContent("Empty result") });
    }
}

2) Erstellen Sie einen benutzerdefinierten Controller mit einer neuen Methode:

public class CustomApiController : ApiController
{
    public IHttpActionResult EmptyResult()
    {
        return new EmptyResult();
    }
}

Und dann kann ich sie in meinen Controllern so aufrufen:

public IHttpActionResult SomeMethod()
    {
       return EmptyResult();
    }
0
Merchezatter

Ein ausführlicheres Beispiel mit Unterstützung von HTTP-Code, der nicht in C # HttpStatusCode definiert ist.

public class MyController : ApiController
{
    public IHttpActionResult Get()
    {
        HttpStatusCode codeNotDefined = (HttpStatusCode)429;
        return Content(codeNotDefined, "message to be sent in response body");
    }
}

Content ist eine virtuelle Methode, die in der abstrakten Klasse ApiController, der Basis des Controllers, definiert ist. Siehe die Erklärung wie folgt:

protected internal virtual NegotiatedContentResult<T> Content<T>(HttpStatusCode statusCode, T value);
0
themefield

Darüber hinaus sind die Dinge wirklich hilfreich.

Bei der Erstellung von Web-Services wird der Verbraucher den Service-Service zu schätzen wissen. Ich habe versucht, die Einheitlichkeit der Ausgabe aufrechtzuerhalten. Sie können auch eine Bemerkung oder eine tatsächliche Fehlermeldung angeben. Der Web-Service-Consumer kann nur IsSuccess auf true prüfen, sonst wird sichergestellt, dass ein Problem vorliegt, und kann entsprechend der Situation verhalten werden. 

  public class Response
    {
        /// <summary>
        /// Gets or sets a value indicating whether this instance is success.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is success; otherwise, <c>false</c>.
        /// </value>
        public bool IsSuccess { get; set; } = false;

        /// <summary>
        /// Actual response if succeed 
        /// </summary>
        /// <value>
        /// Actual response if succeed 
        /// </value>
        public object Data { get; set; } = null;

        /// <summary>
        /// Remark if anythig to convey
        /// </summary>
        /// <value>
        /// Remark if anythig to convey
        /// </value>
        public string Remark { get; set; } = string.Empty;
        /// <summary>
        /// Gets or sets the error message.
        /// </summary>
        /// <value>
        /// The error message.
        /// </value>
        public object ErrorMessage { get; set; } = null;


    }  




[HttpGet]
        public IHttpActionResult Employees()
        {
            Response _res = new Response();
            try
            { 
                DalTest objDal = new DalTest(); 
                _res.Data = objDal.GetTestData();
                _res.IsSuccess = true;
                return Ok<Response>(_res);
            }
            catch (Exception ex)
            {
                _res.IsSuccess = false;
                _res.ErrorMessage = ex;
                return ResponseMessage(Request.CreateResponse(HttpStatusCode.InternalServerError, _res )); 
            } 
        }

Gerne können Sie uns einen Vorschlag machen :)

0
Amol Khandagale