WCF 服务引用命名空间与原始命名空间不同 [英] WCF service reference namespace differs from original

查看:22
本文介绍了WCF 服务引用命名空间与原始命名空间不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having a problem regarding namespaces used by my service references. I have a number of WCF services, say with the namespace MyCompany.Services.MyProduct (the actual namespaces are longer).
As part of the product, I'm also providing a sample C# .NET website. This web application uses the namespace MyCompany.MyProduct.

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

During initial development, the service was added as a project reference to the website and uses directly. I used a factory pattern that returns an object instance that implements MyCompany.Services.MyProduct.IMyService. So far, so good.

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

Now I want to change this to use an actual service reference. After adding the reference and typing MyCompany.Services.MyProduct in the namespace textbox, it generates classes in the namespace MyCompany.MyProduct.MyCompany.Services.MyProduct. BAD! I don't want to have to change using directives in several places just because I'm using a proxy class. So I tried prepending the namespace with global::, but that is not accepted.

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

Note that I hadn't even deleted the original assembly references yet, and "reuse types" is enabled, but no reusing was done, apparently. However, I don't want to keep the assembly references around in my sample website for it to work anyway.

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

The only solution I've come up with so far is setting the default namespace for my web application to MyCompany (because it cannot be empty), and adding the service reference as Services.MyProduct. Suppose that a customer wants to use my sample website as a starting point, and they change the default namespace to OtherCompany.Whatever, this will obviously break my workaround.

这个问题有好的解决办法吗?

Is there a good solution to this problem?

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

To summarize: I want to generate a service reference proxy in the original namespace, without referencing the assembly.

注意:我见过 这个问题,但没有提供我的用例可以接受的解决方案.

Note: I have seen this question, but there was no solution provided that is acceptable for my use case.

正如 John Saunders 所建议的,我已就此向 Microsoft 提交了一些反馈:
反馈项@Microsoft Connect

As John Saunders suggested, I've submitted some feedback to Microsoft about this:
Feedback item @ Microsoft Connect

推荐答案

我添加了一个 这个解决方案的文章到我的博客.确实是相同的信息,但可能不那么分散

I've added a write-up of this solution to my blog. The same information really, but perhaps a little less fragmented

我找到了使用 svcutil.exe 的替代方法来完成我想要的.它 (imo) 使更新服务引用比重新运行实用程序更容易.

I've found an alternative to using svcutil.exe to accomplish what I want. It (imo) makes updating the service reference easier than rerunning the utility.

您应该在您的 ServiceContract 和 DataContracts 上明确指定一个命名空间 uri(请参阅下面的进一步评论).

You should explicitly specify a namespace uri on your ServiceContract and DataContracts (see further below for comment).

[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,所以我选择了这个方案.您可能需要手动构建以便以后工作,所以这样做.

The namespace could be anything, but technically it needs to be a valid uri, so I chose this scheme. You might have to build manually for things to work later, so do that.

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

Once this is done, enable the Show All Files option in the Solution Explorer. Expand the service reference you added previously. Double click the Reference.svcmap file.

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

There will be a <NamespaceMappings /> element, which you will need to edit. Continuing my example:

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

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

Save the file, right click the service reference and select Update Service Reference.

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

You can add as many mappings as you need (I actually needed two). The effect is the same as the svcutil /namespace: approach, but without having to use the command line util itself, making for easier updating.

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

The downside to this approach is that you need to use explicit namespace mappings. Using svcutil, you have the option to map everything not explicitly mapped like this (the solution John Saunders was referring to):

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

您可能会考虑使用:

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

但这将工作,因为 Visual Studio 已经隐式添加了这个映射,指向我们试图摆脱的生成的命名空间名称.上述配置会导致 Visual Studio 报错 key 重复.

but this will not work, because Visual Studio already implicitly adds this mapping, pointing to the generated namespace name we're trying to get rid of. The above configuration will cause Visual Studio to complain about a duplicate key.

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

Ad explicit namespaces:
When no explit namespace is specified in your code, it seems that .NET will generate a uri of the form http://schemas.datacontract.org/2004/07/MyCompany.Services.MyProduct. You could map that just as well as the explicit namespaces in my example, but I don't know if there is any guarantee for this behavior. Therefore, going with an explicit namespace might be better.

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

这篇关于WCF 服务引用命名空间与原始命名空间不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆