13

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

在最初的开发过程中,该服务作为项目引用添加到网站并直接使用。我使用了一个工厂模式,它返回一个实现MyCompany.Services.MyProduct.IMyService. 到现在为止还挺好。

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

请注意,我什至还没有删除原始程序集引用,并且启用了“重用类型”,但显然没有进行重用。但是,我不想在我的示例网站中保留程序集引用,以使其正常工作

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

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

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

注意:我已经看到了这个问题,但是没有提供我的用例可以接受的解决方案。


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

4

3 回答 3

23

我已在我的博客中添加了有关此解决方案的文章。确实是相同的信息,但可能不那么分散

我找到了一种替代方法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
}

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

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

将有一个<NamespaceMappings />元素,您需要对其进行编辑。继续我的例子:

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

保存文件,右键单击服务引用并选择更新服务引用

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

与 svcutil 的区别

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

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

您可能会考虑使用:

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

但这不起作用,因为 Visual Studio 已经隐式添加了这个映射,指向我们试图摆脱的生成的命名空间名称。上述配置将导致 Visual Studio 抱怨重复键。

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

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

于 2009-07-29T19:17:34.930 回答
1

你的用例是错误的。

您一开始就不应该将该服务作为参考。

我相信 svcutil.exe 将接受一个指定要使用的完整命名空间的开关。

于 2009-07-29T15:33:49.440 回答
0

在 VS2010 及更高版本中,有一种设置自定义命名空间的方法。在解决方案资源管理器中,选择“显示所有文件”,然后在解决方案树中打开“Web 引用”,选择服务,选择 Reference.map 节点,显示属性并设置自定义工具命名空间属性。

不幸的是,我没有足够的声誉来显示屏幕截图。

于 2013-10-29T10:02:23.570 回答