Je retourne une gamme d'objets à une page qui rend un diaporama basé sur un album photo.
Je vais chercher mes images de la base de données. P>
Avant de retourner ce tableau. Je voudrais aborder une propriété d'URL "Miniature". Cette propriété n'existe pas sur l'albumpicture, mais je le veux dans la réponse. P>
Ceci illustre l'idée: p> Quelle est la manière la plus élégante Pour ajouter ce champ JSON à mon ensemble de résultats? P> Cette question est si élémentaire qu'il s'agit probablement d'une duplication. Cependant, j'ai googlé pendant 10 minutes et je ne pouvais trouver que Janky Solutions qui dépendent des bibliothèques tierces. Je suis intéressé par la "meilleure pratique" actuelle. P> Dupliqué possible de: Comment ajouter dynamiquement plus de propriétés à la réponse JSON du contrôleur . Cependant, cette réponse rendra les champs de champs ajoutés de manière dynamique des oncles au lieu de frères et sœurs à mes propriétés d'albumpicture dans le JSON résultant. P> P>
9 Réponses :
Actuellement, l'objet dynamique de prise en charge de C # 4.0, vous pouvez donc utiliser un objet dynamique pour ajouter vos propriétés comme heure d'exécution.
Tout d'abord, ajoutez cette méthode d'extension à votre code: P>
var pics = db.AlbumPictures.Where(p => p.AlbumID == album.ID)
.OrderBy(p => p.RankOrder)
.Select(p=>
{ dynamic copy = p.ToDynamic();
copy.Thumbnail = ThumbManager.GetThumb(p.ID); //You can add more dynamic properties here
return copy;
})
.ToList();
return Json(pics, JsonRequestBehavior.AllowGet);
Tout d'abord, merci pour la réponse. S'il s'agit du code le plus élégant pour faire ce que je veux, Microsoft a vraiment besoin d'obtenir ce problème, de la conception de la langue. Je commence à comprendre pourquoi les gens pensent que nœud.js est cool.
Je pense que la conversion de l'objet en objet dynamique est la meilleure façon de résoudre votre problème. Si la solution fonctionne pour vous, veuillez marquer ma réponse comme bonne réponse.
@Johnshedletsky Vous parlez de langues conçues fondamentalement différentes. L'argument des langues dynamiques vs fortement dactylographiés pourrait rage pendant des jours.
@Oliver Il n'est pas difficile d'imaginer une extension au mot-clé Var qui pourrait le faire fonctionner comme des variables dans JavaScript. Juste parce que c # peut être fortement typé, cela ne signifie pas que le code qui touche JSON doit avoir l'air affreux.
La réponse conanak99 fournie est à mon avis la bonne façon de le faire. Des extensions comme celles-ci sont généralement cachées dans vos services centraux de toute façon, et donc la nature réutilisable de sa réponse. Si vous êtes sûr que vous ne l'utiliserez que pour cette fin, vous pouvez le refroidir à
var pics = db.AlbumPictures.Where(p => p.AlbumID == album.ID)
.OrderBy(p => p.RankOrder)
.Select(p =>
{
AlbumExt tmp = new AlbumExt();
AutoMapper.Mapper.DynamicMap(p, tmp);
tmp.Thumbnail = "new prop value";
return tmp;
})
.ToList();
Par rapport au nœud.js Way de le faire, c'est laid comme péché.
Le premier moyen Andrej ne montre-t-il pas à peu près ce que vous avez donné à titre d'exemple dans votre question? Il y a une fonction d'aide oui, mais c'est juste au même endroit. Ensuite, le code à utiliser n'est que P.AppendProperty dans la sélection et aucun besoin pour un forach.
Je suis d'accord avec la plupart des réponses ci-dessus, à l'aide d'un objet dynamique ou d'un objet d'expansion, vous pouvez ajouter la propriété supplémentaire, etc. Cependant, la tâche est simple et, à mon avis, vous ne devez jamais exposer votre objet d'entité à l'interface utilisateur ou aux consommateurs. Je créerais simplement un point de vue simple et le transmettre à l'appelant comme suit:
Si vous utilisez une méthodologie comme MVVM, MVC, MVP, puis utilisez un point de vue, comme suggère Qamar, pour renvoyer la propriété Ajout avec Comtableapper pour mapper les propriétés en cas de besoin.
C'est ce que j'ai fait dans mon code, mais j'ai l'impression d'écrire trop de plomberie.
Même cela implique un peu de plomberie créant un type supplémentaire, etc. Votre contrôleur est donc de la vue ou du consommateur n'est pas au courant de vos objets de domaine. Si vous pensez que c'est la réponse, veuillez la marquer comme réponse
C'est ce que j'ai fini par faire. Conception de la langue - Sage Je pense que Microsoft devrait s'éloigner de ce style de code de Pedantic pour le Web. Mais ce n'est que mon opinion.
Pas directement une réponse à votre question, mais il me semble que vous utilisez quelque chose comme le cadre d'entité pour gérer votre connexion de base de données avec une approche "Database First". Maintenant, vous ne voulez pas ajouter la propriété "Thumbnail" de la base de données, mais je ne veux pas non plus modifier les modèles créés de manière dynamique.
Maintenant, je pense que la meilleure approche serait d'ajouter la propriété au modèle et non juste pour le Json. Dans mon opionion, il sera beaucoup plus facile d'utiliser et permettra également d'utiliser la vignette directement dans une vue si vous en avez besoin si vous en avez besoin. P>
J'ajouterais une classe au projet de base de données appelé évidemment, il sera également ajouté à la sortie JSON. P> Si vous utilisez le code, vous pouvez d'abord utiliser l'annotation code> NotMapped code> pour vous assurer qu'une propriété n'est pas créée dans la base de données. Voir Ignoriser une propriété de classe dans l'entité framework pour plus de détails sur différentes versions. Donc, dans votre cas, ce serait quelque chose comme ce qui suit. Vous pouvez modifier le get / régler sur ce que vous voulez. P> ExtendedModels.cs code> et ajoutez quelque chose comme les suivants p>
J'utilise le Cadre d'entité avec le code en premier. Si je crée une propriété de modèle sans setter, cela crée-t-il toujours une colonne dans la base de données sous-jacente?
Si mon modèle est utilisé dans de nombreux contextes, chacun avec son propre ensemble de propriétés supplémentaires, semble-t-il que j'ajouterais beaucoup de propriétés non acquises à mes modèles? Et les réponses deviendraient gonflées d'informations qui ne sont pas pertinentes contextuelles.
Si vous ne voulez pas envoyer de réponses avec des informations inutiles, vous devez utiliser ViewModels SLA @qamar. Pour que les informations soient stockées à l'objet, elle appartient, est simplement une sension commune dans mon Opnion.
Séparez les propriétés dynamiques du domaine à l'aide d'une projection et d'un objet anonyme.
var pics = db.AlbumPictures
.Where(p => p.AlbumID == album.ID)
.OrderBy(p => p.RankOrder)
.Select(p => new { album = p, Thumbnail = ThumbManager.GetThumb(p.ID))
.ToList();
Vous pouvez utiliser un type anonyme pour créer un nouveau type avec des propriétés albumpicture et la vignette.
Voici le code modifié. p> et vous obtiendrez un résultat JSON quelque chose comme ceci p> J'espère que cela vous aide. P> < / p>
Vous pouvez utiliser json.net pour les convertir en objets et ajouter de manière dynamique les propriétés sur le travail Jobjectis qui est créé.
à partir de là, vous pouvez renvoyer la chaîne JSON en tant que contenu de l'action. p>
Je recommanderais de créer un objet de transfert de données basé sur votre objet albumpicture.
List<AlbumPicture> pics = db.AlbumPictures.Where(p => p.AlbumID == album.ID).OrderBy(p => p.RankOrder).ToList(); return Json(pics.Select(AlbumPicturesDto.AsDto),JsonRequestBehavior.AllowGet);
Ce n'est pas que .Net est mauvais à Json, c'est juste qu'il s'agit d'une langue fortement dactylographiée qui signifie que vous ne pouvez pas le comparer avec une langue dynamique comme JavaScript lors de la gestion des opérations dynamiques sur des types.
À mon avis. , la meilleure façon d'atteindre le résultat souhaitée est de créer de nouvelles classes pour le côté client. Il est en général une mauvaise idée d'utiliser vos modèles de domaine directement pour communiquer avec le client. Au mieux, vous pouvez simplement créer des menaces de vue hériter de vos modèles de domaine si vous souhaitez que la duplication moins possible du code est possible. Mais comme dit, vous ne voulez probablement pas exposer toutes les propriétés de votre modèle à vos clients. P>
Si l'exposition complète du modèle est destinée, vous pourriez faire comme @ conanak99 pointant dans son excellente réponse. Le code pourrait être beaucoup plus élégant en utilisant son formulaire Linq: p>
Renvoyer une collection d'objets anonymes contenant l'objet et la propriété supplémentaire
Oui! C'est exactement ce que je veux faire. Y a-t-il une bonne façon de créer un objet anonyme d'un objet non symbolique?
Quelque chose comme
var données = photos.select (p => nouvelle {image = p, miniature = thumbmanager.getthumb (p.id)}); retour (données); code> - vous n'avez pas donné assez d'informations savoir exactement ce que vous devez revenir)Albumpictures est un modèle avec des champs. Je veux que la propriété de la vignette soit une frère à ces champs - ce que vous suggérez de le faire en faire un oncle (frère des parents) dans le Json émis.
Est-ce vraiment un problème (vous pouvez toujours y accéder à la méthode AJAX), mais vous pouvez toujours utiliser
var données = pics.select (p => nouveau {id = p.Id, nom = P.Name, autreProperty = P.AnotherProperty, ....., vignette = thumbmanager.getthumb (p.id)}); code>Il semble que dégoûtant de retourner un objet JSON imbriqué selon lequel la couche de présentation doit alors connaître et traiter comment elle est imbriquée. Il devrait y avoir un objet de réponse plus javascrectty que vous pouvez ajouter des champs à Willy-Nilly dans C # comme sa hache de hashtable, puis sérialisez JSON sur le serveur.
Qu'en est-il d'utiliser des objets JSON.NET, puis de renvoyer la chaîne JSON générée? James.newtonking.com/json
@Johnshedletsky, votre question et chaque commentaire que vous avez réalisé sont composés de termes subjectifs: c'est-à-dire «Nice», «Jankly Solutions», «Elégant», «Semble affectueux». Si jamais il y avait un candidat à signaler une question d'étant Principalement opiné, le vôtre serait. Et personne ne pense que nœud.js est cool (ou est-ce que cela est parti tel ?!)
@Brian - meilleure réponse jusqu'à présent.