J'ai plusieurs projets qui ont besoin de partager des fichiers de ressources (.resx) Des suggestions ont été faites pour déplacer des fichiers de ressources vers un assembly séparé et faire référence à des projets Web. Y a-t-il un exemple de comment faire cela? Est-ce que je crée un nouveau projet de bibliothèque de classes et déplace le dossier App_GlobalResource à l'intérieur de celui-ci? Je ne pense pas que cela fonctionnera car les classes de code générées pour les fichiers de ressources sont marquées comme 'internes', ce qui signifie qu'elles ne peuvent pas être accédées en dehors de cet assembly.Partage de fichiers de ressources asp.net entre applications Web
Répondre
Dans la fenêtre des propriétés de Visual Studio, vous devez pouvoir définir le modificateur d'accès du fichier de ressources sur public. Cependant, vous ne pourrez pas accéder aux ressources dans les fichiers aspx en utilisant la syntaxe normale <%$ Resources:... %>
, car elle ne prend pas en charge les ressources dans les assemblys référencés. J'ai eu le même problème et l'ai résolu en implémentant un ExpressionBuilder personnalisé, mais je n'ai pas accès à mon code source pour le moment. Si c'est encore nécessaire, je peux regarder le code ce soir.
EDIT: OK, voici comment je l'ai résolu ce problème:
Étape 1: Déplacer les resx dans la bibliothèque de classes. Ils n'ont pas besoin d'être dans un dossier spécifique. Dans le concepteur visuel du fichier resx, définissez le « accès Modificateur » (en haut de coin à droite) à « Public »
Vous devriez maintenant être en mesure de
référence les ressources C#/code VB (dans la bibliothèque, ainsi que dans le projet Web), par exemple,
Dim myMessage As String = [Namespace.]Resources.NameOfResx.NameOfResource
référence à la ressource code en ligne dans les pages ASPX, par exemple,
<h1><%= [Namespace.]Resources.NameOfResx.MyTitle %></h1>
.
Qu'est-ce que ne sera pas travail à ce stade est d'utiliser l'expression de ressources, par exemple, <asp:Button runat="server" Text="<%$ Resources:NameOfResx,MyButtonText %>" />
. Malheureusement, vous ne pouvez pas simplement remplacer ceci par du code en ligne, puisqu'il se trouve dans la propriété d'un contrôle côté serveur.
Étape 2: Créons un ExpressionBuilder personnalisé dans notre bibliothèque, qui interprète des expressions de code arbitraires. Heureusement, nous pouvons laisser les classes puissantes du .net Framework font tout le travail pour nous:
Imports System.Web.Compilation
Imports System.Resources
Imports System.CodeDom
<ExpressionPrefix("Code")> _
Public Class CodeExpressionBuilder
Inherits ExpressionBuilder
Public Overrides Function GetCodeExpression(ByVal entry As System.Web.UI.BoundPropertyEntry, ByVal parsedData As Object, ByVal context As System.Web.Compilation.ExpressionBuilderContext) As System.CodeDom.CodeExpression
Return New CodeSnippetExpression(entry.Expression)
End Function
End Class
Ensuite, nous avons besoin d'enregistrer ce ExpressionBuilder dans le web.config:
<system.web>
...
<compilation ...>
<expressionBuilders>
<add expressionPrefix="Code" type="NamespaceOfYourLibrary.CodeExpressionBuilder" />
</expressionBuilders>
</compilation>
</system.web>
Maintenant, vous devriez être en mesure de faire ce qui suit:
<asp:Button runat="server" Text="<%$ Code:[Namespace.]Resources.NameOfResx.MyButtonText %>" />
crédit: J'ai eu l'idée de la CodeExpressionBuilder du Infinites Loop blog. Si vous êtes plus en C# qu'en VB, vous pouvez regarder les exemples de code ici.
Nous avions une application déjà développée où nous devions avoir 2 copies de tous les fichiers de ressources, un pour les services et un pour le projet asp.net, aussi le projet s'appuyait sur la syntaxe <%$ Resources:NameOfResx,MyButtonText %>
. .
Après un certain temps j'ai trouvé le ExpressionBuilder et est venu avec la solution suivante:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Web.Compilation;
using System.Resources;
using System.CodeDom;
using System.Reflection;
/// <summary>
/// This class allows asp.net Resource lookups to different assembly
/// </summary>
[ExpressionPrefix("Resources")]
public class ResourceExpressionBuilder : ExpressionBuilder
{
static readonly Dictionary<string, ResourceManager> mResourceManagers = new Dictionary<string, ResourceManager>(StringComparer.OrdinalIgnoreCase);
static ResourceExpressionBuilder()
{
Assembly resourceAssembly = Assembly.GetAssembly(typeof(OneTypeInResourceAssembly));
const string suffix = ".resources";
string assemblyName = resourceAssembly.GetName().Name;
foreach (string resource in resourceAssembly.GetManifestResourceNames()) {
if ((resource.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))) {
string resourceName = resource.Substring(0, resource.Length - suffix.Length);
string resourceFriendlyName = resourceName.Substring(assemblyName.Length + 1, resourceName.Length - (assemblyName.Length + 1));
mResourceManagers.Add(resourceFriendlyName, new ResourceManager(resourceName, resourceAssembly));
}
}
}
/// <summary>
/// When overridden in a derived class, returns a value indicating whether the current <see cref="T:System.Web.Compilation.ExpressionBuilder" /> object supports no-compile pages.
/// </summary>
/// <returns>true if the <see cref="T:System.Web.Compilation.ExpressionBuilder" /> supports expression evaluation; otherwise, false.</returns>
public override bool SupportsEvaluate {
get { return true; }
}
/// <summary>
/// When overridden in a derived class, returns an object that represents an evaluated expression.
/// </summary>
/// <param name="target">The object containing the expression.</param>
/// <param name="entry">The object that represents information about the property bound to by the expression.</param>
/// <param name="parsedData">The object containing parsed data as returned by <see cref="M:System.Web.Compilation.ExpressionBuilder.ParseExpression(System.String,System.Type,System.Web.Compilation.ExpressionBuilderContext)" />.</param>
/// <param name="context">Contextual information for the evaluation of the expression.</param>
/// <returns>
/// An object that represents the evaluated expression; otherwise, null if the inheritor does not implement <see cref="M:System.Web.Compilation.ExpressionBuilder.EvaluateExpression(System.Object,System.Web.UI.BoundPropertyEntry,System.Object,System.Web.Compilation.ExpressionBuilderContext)" />.
/// </returns>
public override object EvaluateExpression(object target, System.Web.UI.BoundPropertyEntry entry, object parsedData, System.Web.Compilation.ExpressionBuilderContext context)
{
if ((parsedData != null && object.ReferenceEquals(parsedData.GetType(), typeof(string)))) {
return GetRequestedValue(Convert.ToString(parsedData));
}
return base.EvaluateExpression(target, entry, parsedData, context);
}
/// <summary>
/// When overridden in a derived class, returns code that is used during page execution to obtain the evaluated expression.
/// </summary>
/// <param name="entry">The object that represents information about the property bound to by the expression.</param>
/// <param name="parsedData">The object containing parsed data as returned by <see cref="M:System.Web.Compilation.ExpressionBuilder.ParseExpression(System.String,System.Type,System.Web.Compilation.ExpressionBuilderContext)" />.</param>
/// <param name="context">Contextual information for the evaluation of the expression.</param>
/// <returns>
/// A <see cref="T:System.CodeDom.CodeExpression" /> that is used for property assignment.
/// </returns>
public override System.CodeDom.CodeExpression GetCodeExpression(System.Web.UI.BoundPropertyEntry entry, object parsedData, System.Web.Compilation.ExpressionBuilderContext context)
{
CodeExpression[] inputParams = new CodeExpression[] { new CodePrimitiveExpression(entry.Expression.Trim()) };
return new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(this.GetType()), "GetRequestedValue", inputParams);
}
/// <summary>
/// Gets the requested value.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static object GetRequestedValue(string expression)
{
string[] parts = expression.Split(new char[] { ',' }, 2, StringSplitOptions.None);
if ((parts.Length != 2)) {
throw new ArgumentException("Expression must contain ,");
}
string resourceFile = parts[0].Trim();
string resourceName = parts[1].Trim();
return mResourceManagers[resourceFile].GetString(resourceName);
}
}
Remplacer OneTypeInResourceAssembly
avec un type dans l'ensemble contenant les ressources.
Après cela, vous pouvez simplement ajouter ce qui suit à web.config et il devrait fonctionner ..
<system.web>
<compilation>
<expressionBuilders>
<remove expressionPrefix="Resources" />
<add expressionPrefix="Resources" type="Assembly.ResourceExpressionBuilder" />
</expressionBuilders>
</compilation>
</system.web>
Nice. Cela marche! – Fanda
- 1. Session de partage Asp.Net sur plusieurs applications Web?
- 2. Partage de ressources entre frères et sœurs
- 3. objet session de partage entre les différentes applications web
- 4. Partage de fichiers de bibliothèque entre apks
- 5. WPF: Partage de ressources entre les assemblages
- 6. Fichiers de ressources ASP.Net
- 7. Partage des paramètres entre applications
- 8. Partage de code entre les applications
- 9. IIS7: Partage de sessions entre applications avec le serveur d'état
- 10. Partage de chaînes de connexion entre deux applications .NET
- 11. profil Partage et rôles informations entre les applications web
- 12. Partage d'un HttpRuntime.Cache entre deux applications IIS
- 13. Configuration de partage entre l'application console et l'application Web asp.net
- 14. Partage de l'authentification entre ASP.NET et WordPress
- 15. Téléchargement de fichiers dans les applications Web ASP.Net MVC
- 16. ASP.NET - partage Colonnes entre GridViews
- 17. Comment partager des ressources Web communes entre des applications Web dans Visual Studio?
- 18. Établir l'authentification unique et le partage de session entre deux applications Web s'exécutant sur Tomcat 6
- 19. Partage d'informations entre deux applications XUL
- 20. Partage de base de données entre applications iPhone
- 21. Partage de l'authentification entre les sites ASP.NET
- 22. Partage de session entre 2 demandes ASP.NET
- 23. Partage de ressources entre le service et l'application dans Android
- 24. ASP.NET Partage d'une logique de contrôle utilisateur/page Web avec plusieurs applications Web
- 25. Partage de vues partielles ASP.NET MVC entre projets
- 26. partage des contrôles utilisateur Web entre projets
- 27. Partage de données entre applications sur un iDevice
- 28. Techniques de partage d'une configuration entre deux applications?
- 29. Partage de ressources d'origine croisée
- 30. opérations de partage entre les applications Web, qui fonctionnent dans le même cluster
Il est bon de savoir que je ne serai pas d'accéder aux ressources capables dans les fichiers ASPX (son certainement utilisé comme ça). Ce serait bien de voir ce ExpressionBuilder personnalisé si vous pouvez le partager. –
@ dev.e.loper: J'ai mis à jour ma réponse. – Heinzi
@Heinzi: Cette solution ne rend pas l'assembly séparé pour résoudre les ressources par culture. Vous obtiendrez toutes les chaînes pour la culture par défaut même si theres défini un resx supplémentaire pour la culture actuelle. – Sergio