放置WCF名称空间与否之间的区别?

时间:2014-04-17 14:40:24

标签: c# asp.net wcf

我正在关注此tutorial,并在完成上一个教程后遇到了这个article

令我惊讶的是[ServiceContractAttribute]。我看到文章中的[ServiceContract]没有Namespace,但教程中有一个。

所以我继续将[ServiceContract(Namespace="SandwichServices")]更改为[ServiceContract],但是当我运行应用程序并单击按钮时,我得到一个例外:Uncaught ReferenceError: SandwichServices is not defined

所以我想知道,

  1. 除了还原更改之外,有没有办法解决此错误?也许Web.config就是答案,但我不确定我是否走在正确的轨道上。
  2. 两个[ServiceContractAttribute]有什么区别?从我的角度来看,接口不需要Namespace,但我是对的吗?
  3. Web.config文件内容:

    <system.serviceModel>
      <behaviors>
        <endpointBehaviors>
          <behavior name="SandwichServices.CostServiceAspNetAjaxBehavior">
            <enableWebScript />
          </behavior>
        </endpointBehaviors>
      </behaviors>
    
      <serviceHostingEnvironment
          aspNetCompatibilityEnabled="true" 
          multipleSiteBindingsEnabled="true" />
    
      <services>
        <service name="SandwichServices.CostService">
          <endpoint address="" 
              behaviorConfiguration="SandwichServices.CostServiceAspNetAjaxBehavior" 
              binding="webHttpBinding"
              contract="SandwichServices.CostService" />
        </service>
      </services>
    </system.serviceModel>
    

3 个答案:

答案 0 :(得分:7)

您是对的,合约定义中不需要ServiceContractAttribute的namespace属性,但默认为&#34; http://tempuri.org&#34;。这用于在WSDL中定义端口类型的命名空间。从您的问题中不清楚为什么会发生错误。

使用urn格式的非默认命名空间(例如,urn:companyname:servicename)是一种很好的做法(特别是对于面向外部的API)。此外,您可以使用Name属性进一步定义服务。

示例:

用于菜单服务

[ServiceContract(Name="menu", Namespace="urn:subway:sandwich")] 

订购服务

[ServiceContract(Name="order", Namespace="urn:subway:sandwich")]

通常,您会将WSDL名称空间与代码中的CLR名称空间相匹配。

结合这个例子:

namespace Subway.Sandwich
{
   [ServiceContract(Name="menu", Namespace="urn:subway:sandwich")]
   public interface MenuService
   {

   }

   [ServiceContract(Name="order", Namespace="urn:subway:sandwich")]
   public interface OrderService
   {

   }
}

回答您的具体问题。

  1. 相关信息不足以了解(但可能与配置有关)。
  2. ServiceContract和ServiceContractAttribute是相同的,不需要名称空间。

答案 1 :(得分:1)

关于这个特定的教程,在我的情况下,从ServiceContractAttribute中删除命名空间后)就足以改变这一行:

var service = new SandwichServices.CostService();

var service = new CostService();

在Javascript部分。一切都有效。

您可以在PeterB's answer找到更多解释。

答案 2 :(得分:1)

我还倾向于认为您在更改命名空间后忘记更新客户端应用程序的服务引用。它的工作方式与.NET类完全相同。让我们考虑一个例子。您在命名空间SuperClass中有一个名为MyProject.SuperClasses的类。您已经在代码中的某个位置使用了该类,然后您将更改该类的命名空间。您很可能会遇到构建错误,并且必须为新命名空间添加使用语句。

还有一些现实生活中的例子,您应该指定命名空间:

1

  

您应始终指定数据协定的名称和命名空间   防止暴露您的.NET类型的名称和命名空间   合约。这样,如果您稍后决定更改.NET   名称空间或类型名称,您的数据合同保持不变。

简单来说,如果指定了名称空间,如果您决定进行重构并重命名类或属性,则不会破坏现有客户端。

2

命名空间通常用于版本化WCF服务。我甚至会说使用命名空间来版本化WCF服务是一种最佳实践。因此,您应该仔细设计命名空间,并将版本信息包含在其中:

http://schemas.contoso.com/2005/05/21/PurchaseOrder

如果您希望更改合同并确保现有客户端不会中断,这将极大地简化您的工作。您可以阅读有关here主题的更多信息。

希望它有所帮助!