J'ai trouvé ce billet de blog (http://www.akngo.com/) qui montre comment "envelopper" Htmlstring pour des raisons de commodité. L'utilisation est RawView.SomeString
J'utilise le moteur de rasoir pour quelques jours maintenant, et je suis ce goût beaucoup . J'ai remarqué un gros problème dès le début, toutes les chaînes sont codées en HTML . Pour nos besoins, cela devient une "fonctionnalité" assez gênante lorsque nous traitons des chaînes JSON. Par exemple, donné une simple chaîne JSON, [ "1", "2", "3", "4"]
La sortie codée HTML réelle de ce est devenu, [, , " " 3, 4 " "]
les citations ont été échappé, qui est pas le résultat souhaité. Si nous avons besoin de renvoyer le code HTML, ou XML, nous devrions alors nous échapper individuellement . Dans l'ensemble, je trouve cela tout à fait ennuyeux comme nous aurions à l'envelopper à l'intérieur d'un HtmlString comme indiqué dans ce poste StackOverflow.
Dans notre scénario, nous générons JSON/XML de C#, donc la plupart du temps, nos données sérialisé est à l'intérieur de la ViewModel. Ce qui conduirait à nous faire des choses comme, @ (nouveau HtmlString (View.Foo)) @ (nouveau HtmlString (View.Bar))
Comme vous pouvez le voir, cela peut devenir assez lourd .J'ai donc décidé de partie plagiée de MVC pour créer un RawView. En fin de compte, l'utilisation sera être, @ RawView.Foo @ RawView.Bar
Je suis allé aussi en avance pour permettre l'utilisation de l'opérateur d'index et en cas il y a un besoin de boucle au-dessus avec un liste des clés. // En supposant que nous avons Foo, Bar, et Baz dans notre ViewModel @ { List keys = new List {"Foo", "Bar", "Baz"}; foreach (clé var dans les clés) { @RawView [key] }}
Pour ce faire, il faudrait que je double DynamicViewDataDictionary. Bien entendu, je l'ai appelé DynamicRawViewDataDictionary, publique classe DynamicRawViewDataDictionary: DynamicObject { readonly privé Func viewThunk; public DynamicRawViewDataDictionary (Func viewThunk) { this.viewThunk = viewThunk; }
private ViewDataDictionary ViewData
{
get
{
ViewDataDictionary viewData = this.viewThunk();
return viewData;
}
}
public object this[string key]
{
set { setData(key, value); }
get { return getData(key); }
}
public override IEnumerable<string>
GetDynamicMemberNames() { ViewData.Keys de retour; }
public override bool TryGetMember(GetMemberBinder binder,
à la suite de l'objet) {result = getData (binder.Name); renvoyer true; }
public override bool TrySetMember(SetMemberBinder binder,
valeur d'objet) { setData (binder.Name, valeur); renvoyer true; }
private object getData(string key)
{
object value = ViewData[key];
if (value is string)
{
return new HtmlString(value.ToString());
}
return value;
}
private void setData(string key, object value)
{
ViewData[key] = value;
}
}
La raison de la duplication est parce que le DynamicViewDataDictionary est une classe interne étanche. Il y avait aucun moyen que je pourrais contourner cette restriction autre que la copie et coller. La modification évidente que j'ai apportée à cette classe est la méthode getData. I vérifié pour voir si l'objet est une chaîne , si c'est le cas, je l'ai enveloppé avec un HtmlString().
Maintenant, je dois l'utiliser à l'intérieur d'un WebViewPage, puisque tous les points de vue, je d'avoir une version personnalisée d'un WebViewPage ainsi. Bonne chose que MS n'a pas fait de cette classe interne scellé, donc je peux facilement hériter de il. Je devais faire un générique et une version non générique , j'ai juste plié à la fois de ce à l'intérieur d'un fichier. public abstract class CustomWebViewPage: WebViewPage { privé DynamicRawViewDataDictionary _rawData; RawView dynamique publique { get { if (_rawData == null) { _rawData = new DynamicRawViewDataDictionary (() => ViewData); } return _rawData; }} }
public abstract class CustomWebViewPage : WebViewPage
{
private DynamicRawViewDataDictionary _rawData;
public dynamic RawView
{
get
{
if (_rawData == null)
{
_rawData = new DynamicRawViewDataDictionary(() =>
ViewData); } return _rawData; }} }
Pour la touche finale pour réellement faire ce travail, en haut du fichier cshtml , vous devriez avoir quelque chose comme, @inherits Namespace.To.CustomWebViewPage
// ou @inherits Namespace.To.CustomWebViewPage
maintenant que le fichier cshtml hérite de la nouvelle CustomWebViewPage, il devrait avoir accès à RawView, WHIC h va envelopper toutes les chaînes avec un HtmlString.
Une fois que vous avez cela en place, vous aurez besoin encore pour vous assurer que tous vos nouvelles vues hérite de CustomWebViewPage. Je recommande fortement en utilisant des modèles de code personnalisés dans votre projet MVC pour générer la vue. Ce aidera à automatiser un grand nombre des tâches banales .
La méthode ne montre pas réellement qu'elle retourne la chaîne codée dans le débogueur, c'est juste que la vue l'écrit de cette façon. – brooks