Question Quelle est la différence entre HttpResponseMessage et HttpResponseException


J'ai essayé de comprendre les deux et d'écrire un exemple de code:

 public HttpResponseMessage Get()
 {
     var response = ControllerContext.Request
                         .CreateResponse(HttpStatusCode.BadRequest, "abc");

     throw new HttpResponseException(response);
 }

Et:

 public HttpResponseMessage Get()
 {
     return ControllerContext.Request
                        .CreateResponse(HttpStatusCode.BadRequest, "abc");
 }

De Fiddle, je n'ai vraiment pas vu de différences entre eux, alors quel est le but d'utiliser HttpResponseException?


56
2018-05-18 22:56


origine


Réponses:


La principale différence entre les deux est la suivante. L'exception est utile pour arrêter immédiatement le traitement et quitter. Par exemple, supposons que j'ai le code suivant

public class CustomerController : ApiController {
  private ICustomerContext repo;

  public CustomerController(ICustomerContext repo) {
    this.repo = repo;
  }

  public Customer Get(int id) {
    var customer = repo.Customers.SingleOrDefault(c=>c.CustomerID == id);
    if (customer == null) {
      throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    }
    return customer;
  }
}

Si ce code s'exécute et que je passe un identifiant qui n'est pas présent, il arrête immédiatement le traitement et renvoie un code d'état de 404.

Si, au lieu de cela, je retourne HttpResponseMessage, la requête continuera avec plaisir le reste du traitement et retournera un 404. La principale différence est la fin de la requête ou non.

Comme Darrel l'a dit, l'exception est utile dans les cas où, dans certains cas, je souhaite que le traitement continue (comme lorsque le client est trouvé) et dans d'autres, je ne le fais pas.

L'emplacement où vous souhaitez peut-être utiliser quelque chose comme HttpResponseMessage se trouve dans un POST HTTP pour renvoyer un code d'état de 201 et définir l'en-tête de l'emplacement. Dans ce cas, je souhaite que le traitement continue. Cela ferait avec ce code.

public class CustomerController : ApiController {
  private ICustomerContext repo;

  public CustomerController(ICustomerContext repo) {
    this.repo = repo;
  }

  public HttpResponseMessage Post(Customer customer) {
    repo.Add(customer);
    repo.SaveChanges();
    var response = Request.CreateResponse(HttpStatusCode.Created, customer);
    response.Headers.Location = new Uri(Request.RequestUri, string.format("customer/{0}", customer.id));
    return response;
  }
}

* note: Si vous utilisez les bits bêta, vous créez un nouveau message HttpResponseMessage. J'utilise cependant les derniers bits qui nécessitent l'utilisation de la méthode d'extension CreateResponse hors de la requête.

Ci-dessus, je crée une réponse qui définit le code de statut sur 201, passe le client et définit ensuite l'en-tête de l'emplacement.

La réponse est ensuite renvoyée et la demande continue le traitement.

J'espère que cela t'aides


66
2018-05-24 09:18



HttpResponseException est utile lorsque votre signature d'action de contrôleur ressemble à

  Foo Get(int id)

Dans ce cas, vous ne pouvez pas retourner facilement le code d'état comme 400.

Soit conscient que HttpResponseMessage<T> s'en va dans la prochaine version de Web API.


28
2018-05-19 03:41



En supposant que vous vouliez tester les réponses par unité, cela n'a-t-il pas de sens de toujours renvoyer un message HttpResponseMessage? Je n'aime pas particulièrement l'idée de renvoyer un type droit à partir d'un ApiController, car il ne suit pas les modèles de développement typiques.

Dans une classe d'API non Web qui a récupéré un client, vous retourneriez probablement null, avec votre code appelant pour vérifier une réponse nulle:

public Customer GetCustomer(int id)
{
    return db.Customers.Find(id);
}

Mais dans Web API, vous n'allez pas retourner null, vous devez retourner quelque chose, même si quelque chose est créé après avoir lancé une exception HttpResponseException. Dans ce cas, pour faciliter les tests, pourquoi ne pas toujours renvoyer un HttpResponseMessage et en faire votre signature?

public HttpResponseMessage GetCustomer(int id)
{
    var customer = db.Customers.Find(id);
    if (customer == null)
    {
        return Request.CreateResponse(HttpStatusCode.NotFound);
    }

    return Request.CreateResponse(HttpStatusCode.OK, customer);
}

13
2018-06-07 14:52



HttpResponseException dérive de Exception et intègre HttpResponseMessage. Depuis qu'il provient de Exception il peut être utile dans try-catch scénarios.

Code d'état par défaut renvoyé par HttpResponseException est HttpStatusCode.InternalServerError.


2
2018-05-19 03:27



Comme l'indiquent les questions d'origine, il n'y a pas de différence réelle dans la réponse renvoyée.

Le véritable objectif de HttpResponseException est de permettre aux sous-méthodes de créer et de "lancer" leurs propres messages HttpResponseMessages qui retournent à la pile d'appels et sont renvoyés au client.

public class CustomerController : ApiController {
  private ICustomerContext repo;
  public CustomerController(ICustomerContext repo) {
    this.repo = repo;
  }

  public HttpResponseMessage Get(int id) {

    Customer customer = getCustomer(id);

    return Request.CreateResponse(customer);
  }

  private Customer getCustomer(int id){
    .....do some work
    .....we have a problem so throw exception
    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, "Id out of range");
    return repo.Customers.SingleOrDefault(c=>c.CustomerID == id)
}

Pardonnez les erreurs, code écrit à la volée. La HttpResponseException lancée jaillit dans la pile d'appels d'actions, n'est pas interceptée par les gestionnaires d'exception normaux et retourne son HttpResponseMessage comme le ferait la méthode d'action elle-même.


0
2017-08-20 20:12