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?
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. :)
Sie können dies verwenden:
return Content(HttpStatusCode.BadRequest, "Any object");
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.
Sie können auch tun:
return InternalServerError(new Exception("SOME CUSTOM MESSAGE"));
Jeder, der daran interessiert ist, irgendetwas mit beliebigem Statuscode und ResponseMessage zurückzugeben:
//CreateResponse(HttpStatusCode, T value)
return ResponseMessage(Request.CreateResponse(HttpStatusCode.XX, object));
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.
Einfach:
return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Your message"));
Denken Sie daran, auf System.Net.Http und System.Net zu verweisen.
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()
@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;
}
}
Ausnahmen mache ich normalerweise
catch (Exception ex)
{
return InternalServerError(new ApplicationException("Something went wrong in this request. internal exception: " + ex.Message));
}
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);
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();
}
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);
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 :)