WCF服务引用名称空间与原始名称不同

Tho*_*rin 13 .net c# wcf namespaces svcutil.exe

关于我的服务引用所使用的命名空间,我遇到了问题.我有很多WCF服务,比如命名空间MyCompany.Services.MyProduct(实际名称空间更长).
作为产品的一部分,我还提供了一个示例C#.NET网站.此Web应用程序使用命名空间MyCompany.MyProduct.

在初始开发期间,该服务被添加为网站的项目参考并直接使用.我使用了一个返回实现的对象实例的工厂模式MyCompany.Services.MyProduct.IMyService.到现在为止还挺好.

现在我想更改它以使用实际的服务引用.添加引用并MyCompany.Services.MyProduct在命名空间文本框中键入后,它会在命名空间MyCompany.MyProduct.MyCompany.Services.MyProduct中生成类.坏!我不想using因为我正在使用代理类而在几个地方更改指令.所以我试着在名称空间前加上global::,但是不接受.

请注意,我还没有删除原始程序集引用,并且启用了"重用类型",但显然没有重用.但是,我不想在我的示例网站中保留程序集引用,以便它仍能正常工作.

到目前为止,我提出的唯一解决方案是将Web应用程序的默认命名空间设置为MyCompany(因为它不能为空),并将服务引用添加为Services.MyProduct.假设客户想要使用我的示例网站作为起点,并将默认命名空间更改为OtherCompany.Whatever,这显然会破坏我的解决方法.

这个问题有一个很好的解决方案吗?

总结一下:我想在原始命名空间中生成服务引用代理,而不引用程序集.

注意:我已经看到了这个问题,但没有提供可用于我的用例的解决方案.


编辑:正如John Saunders建议的那样,我已经向Microsoft提交了一些反馈:
反馈项目@ Microsoft Connect

Tho*_*rin 21

我已经在我的博客中添加了这个解决方案的文章.真的是相同的信息,但也许不那么零散

我找到了另一种svcutil.exe用来完成我想要的东西.它(imo)使得更新服务引用比重新运行实用程序更容易.

您应该在ServiceContract和DataContracts上明确指定名称空间uri(请参阅下面的注释).

[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
}
Run Code Online (Sandbox Code Playgroud)

命名空间可以是任何东西,但从技术上讲它需要是一个有效的uri,所以我选择了这个方案.您可能必须手动构建以便以后工作,所以这样做.

完成此操作后,在解决方案资源管理器中启用" 显示所有文件"选项.展开先前添加的服务引用.双击该Reference.svcmap文件.

将有一个<NamespaceMappings />元素,您需要编辑它.继续我的例子:

<NamespaceMappings>
    <NamespaceMapping
        TargetNamespace="http://company.com/MyCompany.Services.MyProduct"
        ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>
Run Code Online (Sandbox Code Playgroud)

保存文件,右键单击服务引用,然后选择" 更新服务引用".

您可以根据需要添加任意数量的映射(实际上我需要两个).效果与svcutil /namespace:方法相同,但无需使用命令行util本身,便于更新.

与svcutil的区别

这种方法的缺点是您需要使用显式命名空间映射.使用svcutil,您可以选择映射未明确映射的所有内容(John Saunders所指的解决方案):

svcutil /namespace:*,MyCompany.Services.MyProduct ...
Run Code Online (Sandbox Code Playgroud)

您可能会考虑使用:

<NamespaceMappings>
    <NamespaceMapping
        TargetNamespace="*"
        ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>
Run Code Online (Sandbox Code Playgroud)

但是这将不会工作,因为Visual Studio中已经隐含地增加了这种映射,指向我们试图摆脱生成的命名空间名称.上述配置将导致Visual Studio抱怨重复键.

广告显式命名空间:
当您的代码中未指定explit命名空间时,似乎 .NET将生成表单的uri http://schemas.datacontract.org/2004/07/MyCompany.Services.MyProduct.你可以在我的例子中映射那个和显式命名空间一样,但我不知道这种行为是否有任何保证.因此,使用显式命名空间可能会更好.

注意:将两个TargetNamespaces映射到同一个ClrNamespace似乎会破坏代码生成

  • 在遇到这个错误后,我发现这是在SO上发布这个帖子之前的答案,但我不得不说这是非常荒谬的.WCF应该自动执行此操作,没有一个有效的理由要求服务的每个用户手动编辑其客户端文件只是为了与服务进行通信.尽管我喜欢.NET这样的东西让我对微软很生气. (2认同)