Question

Je rencontre un problème concernant les espaces de noms utilisés par mes références de service. J'ai plusieurs services WCF, avec l'espace de noms MyCompany.Services.MyProduct ( les espaces de noms réels sont plus longs ).
Dans le cadre de ce produit, je fournis également un exemple de site Web C # .NET. Cette application Web utilise l'espace de noms MyCompany.MyProduct.

Lors du développement initial, le service a été ajouté en tant que référence de projet sur le site Web et utilisé directement. J'ai utilisé un modèle d'usine qui renvoie une instance d'objet qui implémente MyCompany.Services.MyProduct.IMyService. Jusqu'ici, tout va bien.

Maintenant, je souhaite changer ceci pour utiliser une référence de service réelle. Après avoir ajouté la référence et tapé using dans la zone de texte de l'espace de noms, il génère des classes dans l'espace de noms MyCompany.MyProduct.MyCompany.Services.MyProduct . BAD! Je ne veux pas avoir à changer les directives global:: à plusieurs endroits simplement parce que j'utilise une classe de proxy. J'ai donc essayé de préfixer l'espace de noms avec MyCompany, mais cela n'a pas été accepté.

Notez que je n'avais même pas encore supprimé les références d'assemblage d'origine et & "Réutiliser les types &"; est activé, mais aucune réutilisation n'a été effectuée, apparemment. Toutefois, je ne souhaite pas conserver les références d'assemblage dans mon exemple de site Web pour que cela fonctionne malgré tout .

La seule solution que j'ai trouvée jusqu'à présent consiste à définir l'espace de noms par défaut pour mon application Web sur Services.MyProduct (car il ne peut pas être vide) et à ajouter la référence de service sous la forme OtherCompany.Whatever. Supposons qu'un client souhaite utiliser mon exemple de site Web comme point de départ et modifie l'espace de noms par défaut en <=>. Cela résoudra évidemment ma solution de contournement.

Existe-t-il une bonne solution à ce problème?

Pour résumer : je souhaite générer un proxy de référence de service dans l'espace de nom d'origine, sans faire référence à l'assembly.

Remarque: j’ai vu cette question , mais aucune solution n’était acceptable pour mon cas d’utilisation.

Modifiez: comme l’a suggéré John Saunders, j’ai soumis à Microsoft des commentaires à ce sujet:
Élément de commentaire @ Microsoft Connect

Était-ce utile?

La solution

J'ai ajouté un écrire de cette solution sur mon blog. La même information vraiment, mais peut-être un peu moins fragmentée

J'ai trouvé une alternative à l'utilisation de svcutil.exe pour accomplir ce que je veux. Cela facilite la mise à jour de la référence de service plutôt que de réexécuter l’utilitaire.

Vous devez spécifier explicitement un espace de nom uri sur vos contrats ServiceContract et DataContracts ( voir ci-dessous pour obtenir un commentaire ).

[ServiceContract(Namespace = "http://company.com/MyCompany.Services.MyProduct")]
public interface IService
{
    [OperationContract]
    CompositeType GetData();
}

[DataContract(Namespace = "http://company.com/MyCompany.Services.MyProduct")]
public class CompositeType
{
    // Whatever
}

L'espace de noms peut être n'importe quoi, mais techniquement, il doit s'agir d'un uri valide. J'ai donc choisi ce schéma. Vous devrez peut-être créer manuellement pour que les choses fonctionnent plus tard, alors faites-le.

Une fois cette opération effectuée, activez l'option Afficher tous les fichiers dans l'Explorateur de solutions. Développez la référence de service que vous avez ajoutée précédemment. Double-cliquez sur le Reference.svcmap fichier.

Il y aura un élément <NamespaceMappings /> que vous devrez éditer. Continuant mon exemple:

<NamespaceMappings>
    <NamespaceMapping
        TargetNamespace="http://company.com/MyCompany.Services.MyProduct"
        ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>

Enregistrez le fichier, cliquez avec le bouton droit de la souris sur la référence du service et sélectionnez Mettre à jour la référence du service .

Vous pouvez ajouter autant de mappages que vous avez besoin (j'en avais besoin de deux). L’effet est identique à l’approche svcutil /namespace:, mais ne nécessite pas l’utilisation de la ligne de commande elle-même, ce qui facilite la mise à jour.

Différence avec svcutil

L’inconvénient de cette approche est que vous devez utiliser des mappages d’espaces de noms explicites. En utilisant svcutil, vous avez la possibilité de mapper tout ce qui n’est pas explicitement mappé comme ceci (la solution à laquelle John Saunders faisait référence):

svcutil /namespace:*,MyCompany.Services.MyProduct ...

Vous pourriez penser à utiliser:

<NamespaceMappings>
    <NamespaceMapping
        TargetNamespace="*"
        ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>

mais cela ne fonctionnera pas , car Visual Studio ajoute déjà implicitement ce mappage, en indiquant le nom de l'espace de nom généré que nous essayons de supprimer. La configuration ci-dessus amène Visual Studio à se plaindre d’une clé dupliquée.

Espaces de nom explicites pour les annonces :
Lorsqu'aucun espace de nom explit n'est spécifié dans votre code, il semble que .NET générera un URI de la forme http://schemas.datacontract.org/2004/07/MyCompany.Services.MyProduct . Vous pouvez mapper cela aussi bien que les espaces de noms explicites dans mon exemple, mais je ne sais pas s'il existe une garantie pour ce comportement. Par conséquent, utiliser un espace de nom explicite pourrait être préférable.

NB: le mappage de deux espaces de noms cible sur le même espace mémoire semble interrompre la génération de code

Autres conseils

Votre cas d'utilisation était erroné.

Vous n'auriez jamais dû inclure le service comme référence.

Je pense que svcutil.exe acceptera un commutateur spécifiant l'espace de nom complet à utiliser.

Dans VS2010 et les versions ultérieures, il existe un moyen de configurer des espaces de noms personnalisés. Dans l'explorateur de solutions, sélectionnez & Quot; Afficher tous les fichiers & Quot; puis ouvrez " références Web " dans l'arborescence de la solution, sélectionnez le service, sélectionnez le nœud Reference.map, affichez les propriétés et définissez la propriété Custom Namespace Space.

Malheureusement, je n'ai pas assez de réputation pour afficher une capture d'écran.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top