2009-08-26 10 views
0

Rails a un idiome sympa qui vous permet d'avoir une seule méthode d'action pour retourner des données correctement formées (json, xml, juste les données) en fonction de le format spécifié par le client (ou bien déduite de la demande. Il ressemble à quelque chose comme ça ...Quelle est la meilleure façon de gérer les formats de retour multiples dans ASP.NET MVC

respond_to do |format| 
    format.html #edit.html.erb 
    format.json {render :text=> <your json here>), :layout=> false} 
    format.xml ... 

end 

Quelle est la meilleure façon de le faire dans ASP.NET MVC? Idéalement, je voudrais la framework pour fonctionner de la même manière que Rails (par exemple, être capable de retourner le ViewData correctement formaté pour le format spécifié par le client ou déduit de la demande elle-même). Rails vous permet également de créer des vues spécifiques à chaque type, ce qui vous permet de renvoyer les mêmes données à toutes les vues et de les gérer correctement (vous avez donc une vue qui construit xml, une autre qui construit json et un autre qui construit html). Est-ce possible avec ASP.NET MVC? En fait, ce modèle semble le mieux conserver l'objectif de séparer les préoccupations de l'IMHO puisqu'il permet aux contrôleurs de renvoyer des données agnostiques à la vue alors que la plupart des approches que je vois aujourd'hui (y compris la ligne ci-dessus "format.json ....: layout => false ") effectuer la conversion JSON à l'intérieur du contrôleur et renvoyer ces données directement au client à la demande de ce format.

En tout cas ... des suggestions, des pensées, des recommandations?

Merci

Répondre

2

Dans ASP.NET MVC, les actions du contrôleur général renvoient des objets qui dérivent de ActionResult, qui est ensuite invoquée par le moteur d'exécution tout en générant le flux de réponse.

Out-of-the-box vous avez plusieurs classes qui dérivent ActionResult-ContentResult des résultats texte, ViewResult pour le contenu d'une vue, JsonResult pour sérialisation une hiérarchie d'objets en JSON, RedirectResult pour rediriger, et ainsi de suite.

Généralement, vous passez le modèle au résultat et vous laissez décider comment générer le résultat, mais il n'est pas nécessaire que ce soit le même modèle - je peux passer un objet différent à chaque résultat si nécessaire.

Le type concret de résultat retourné par une action est pas « cuit dans » à la signature de l'action - vous pouvez facilement passer dans un paramètre de format à votre action, et l'ont générer et revenir un autre ActionResult en conséquence:

public ActionResult ListProducts(string format) 
{ 
    List<Product> products = ProductService.GetAllProducts(); 
    if (format == "JSON") 
    { 
     // eg., transform model for JSON consumption 
     List<JsonProduct> jsonProducts = ProductService.ToJSON(products); 
     return Json(jsonProducts); 
    } 
    else if (format == "XML") 
    { 
     return new XmlResult(products); 
    }

// default is to return HTML from view, which expects List<Product> for model 
    return View(products); 

}

Notez que les méthodes Json() et View() sont intégrés dans le contrôleur et sont des méthodes pratiques pour le retour JsonResult et ViewResult respec tivement. XmlResult est un exemple de ActionResult personnalisé qui prend un objet, le sérialise en XML, puis renvoie le résultat sous la forme d'un flux XML.

L'exemple est un peu artificiel, mais il montre que le contrôleur orchestre tout le travail de sélection du résultat et de construction/transformation du modèle qui est passé à ce résultat. Les actions du contrôleur doivent toujours être légères, afin de décharger les lourdes tâches sur les services, par exemple charger le modèle à partir de la couche de gestion ou transformer des objets d'un modèle en objets dans un autre modèle, par exemple pour la consommation JSON.

+0

Le seul problème ici est qu'il est rarement si facile de simplement renvoyer Json (votre modèle).Typiquement, je m'attendrais à ce que les gens utilisent quelque chose comme JQuery ou ExtJs dans le client qui nécessite que le JSON (ou xml) soit structuré d'une manière particulière. Alors ... d'où vient cette restructuration? Si nous devions le faire dans le contrôleur ... où/comment? Aussi, si nous le faisons là ... cela ne viole-t-il pas la «séparation des préoccupations»? Si nous le faisons dans la vue ... comment pouvons-nous modifier le cadre pour choisir intelligemment la bonne vue en fonction du format demandé? Merci. – wgpubs

+0

Je suis d'accord, la plupart du temps, vous aurez besoin d'un modèle distinct pour travailler avec JSON. Je ne vois pas pourquoi la séparation des préoccupations est violée - la préoccupation du contrôleur est de fournir le modèle à la vue, ce qui inclut l'élaboration de ce que ce modèle devrait être, et quelle vue devrait être donnée à ce modèle. C'est tout à fait pertinent pour le contrôleur de le faire. Ce serait certainement une violation si la vue faisait le travail du contrôleur. J'ai édité mon échantillon pour indiquer la construction du modèle. – Sam

+0

Je suppose que je suis un peu déchiré sur celui-ci parce que oui, le contrôleur devrait être responsable de la façon dont les données sont emballées et envoyées à la vue ... mais cela signifie-t-il qu'il devrait en être responsable? des données dans potentiellement de nombreux formats basés sur un ou plusieurs frameworks côté client utilisés (par exemple ExtJs, Jquery, Mootools, etc ...)? Vous voyez, nous ne renvoyons pas juste un tas de données ici ... nous retournons des données pour JQuery ou FOR ExtJs. C'est là que la chose de séparation devient un peu plus obscur et aussi les contrôleurs de tests unitaires un peu plus poilus. – wgpubs

Questions connexes