251 votes

Renvoi du code d'état http du contrôleur ASP.NET MVC 4 Web Api

J'essaie de retourner un code d'état de 304 non modifié pour une méthode GET dans un contrôleur Web Api.

La seule façon dont j'ai réussi était quelque chose comme ceci:

 public class TryController : ApiController
{

public User GetUser(int userId, DateTime lastModifiedAtClient)
{
    var user = new DataEntities().Users.First(p => p.Id == userId);
    if (user.LastModified <= lastModifiedAtClient)
    {
         throw new HttpResponseException(HttpStatusCode.NotModified);
    }
return user;
}
}
 

Le problème ici est que ce n'est pas une exception, ce n'est simplement pas modifié, le cache du client est donc correct. Je souhaite également que le type de retour soit un utilisateur (comme le montrent tous les exemples web api avec GET), il ne renvoie pas HttpResponseMessage ou quelque chose du genre.

Aucune suggestion? Je vous remercie

276voto

Aliostad Points 47792

Je ne connaissais pas la réponse, alors j'ai demandé à l'équipe ASP.NET ici .

L'astuce consiste donc à changer la signature en HttpResponseMessage et utiliser Request.CreateResponse .

 [ResponseType(typeof(User))]
public HttpResponseMessage GetUser(HttpRequestMessage request, int userId, DateTime lastModifiedAtClient)
{
    var user = new DataEntities().Users.First(p => p.Id == userId);
    if (user.LastModified <= lastModifiedAtClient)
    {
         return new HttpResponseMessage(HttpStatusCode.NotModified);
    }
    return request.CreateResponse(HttpStatusCode.OK, user);
}
 

68voto

Vous pouvez également effectuer les opérations suivantes si vous souhaitez conserver la signature d'action en tant qu'utilisateur retournant:

 public User GetUser(int userId, DateTime lastModifiedAtClient) 
 

Si vous voulez retourner quelque chose d'autre que 200, vous lancez une exception HttpResponseException dans votre action et transmettez le message HttpResponseMessage que vous souhaitez envoyer au client.

Henrik

43voto

Luke Puplett Points 4971

Modifiez la méthode API GetXxx pour renvoyer HttpResponseMessage, puis renvoyez une version typée pour la réponse complète et la version non typée pour la réponse NotModified.

     public HttpResponseMessage GetComputingDevice(string id)
    {
        ComputingDevice computingDevice =
            _db.Devices.OfType<ComputingDevice>()
                .SingleOrDefault(c => c.AssetId == id);

        if (computingDevice == null)
        {
            return this.Request.CreateResponse(HttpStatusCode.NotFound);
        }

        if (this.Request.ClientHasStaleData(computingDevice.ModifiedDate))
        {
            return this.Request.CreateResponse<ComputingDevice>(
                HttpStatusCode.OK, computingDevice);
        }
        else
        {
            return this.Request.CreateResponse(HttpStatusCode.NotModified);
        }
    }
 

* Les données ClientHasStale sont mon extension pour vérifier les en-têtes ETag et IfModifiedSince.

Le framework MVC doit toujours sérialiser et renvoyer votre objet.

REMARQUE

Je pense que la version générique est supprimée dans une future version de l'API Web.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X