【问题标题】:Can't access public class from web service无法从 Web 服务访问公共课程
【发布时间】:2018-04-27 13:42:52
【问题描述】:

我有一个非常奇怪的场景,我似乎无法弄清楚发生了什么。我有一个用 C# 编写的 Web 服务,目标框架是 3.5。我有很多类和方法,但为简单起见,我将在问题中仅使用两个类。

public class PathNames
{
   private string _pathA = "Some Path";
   private string _pathB = "Another Path";
   public string BaseDirectoryPath
   {
        get
        {
            return Path.Combine(_pathA, _pathB); 
        }
   }
}

第二类如下:

public class UserInformation
{
   public string UserName { get; set; }
   ...//more properties 
}

以上两个类都在同一个namespace 中。

Web 服务在目标框架为 4.0 的 WebForm 应用程序中引用。一切似乎都运行良好,当我在 Object Browser 中查看 UserInformation 类时,我可以看到它。但是PathNames 类似乎在Object Broswer 中不可见。

有问题的两个源文件在File Properties 窗口中都设置为Compile。我有 5 个类似于 UserInformation 的类和 File Properties 窗口中的相同设置,它们只是简单的 POCO 并且只有公共自动属性。这些似乎都在通过,我可以访问它们并在Object Browser 中查看它们。出于某种奇怪的原因,我无法通过PathNames 课程。我尝试添加一些新的虚拟类,并遇到与PathNames 类相同的问题。有人可以告诉我我做错了什么吗?

  1. 旧版 ASMX 网络服务

  2. 正在通过VS添加服务引用创建Web服务客户端

  3. 使用 VS 2017 专业版 - 版本 15.6.7。

  4. 发布后,如果我反编译 dll,那么 PathNames 类就在那里。所以它显然在 dll 中。

  5. 我查看了 this,但仍然没有运气。

【问题讨论】:

  • 这是 WCF 网络服务吗?还是WebAPI?还是旧的 ASMX? SOAP 还是 REST?请明确说明。您是否使用 DataContact / DataMember 之类的任何属性来装饰您的类?另外你是如何创建你的网络服务客户端的?是通过 Visual Studio 的添加服务参考吗? WSDL 中显示了什么?
  • @Jim 应该是一个 ASMX 一个 OP 谈论
  • 您是否尝试过更新您的服务参考?
  • @Rahul 我已多次更新我的服务参考,甚至将其删除并重新添加
  • @Jim 我已将信息包含在问题中。该类没有装饰任何属性

标签: c# asp.net web-services


【解决方案1】:

在网络服务中使用数据协定

服务不能公开私有/只读属性。 DataMember 属性用于标记带有 DataContract 属性的类的公共成员或属性(带有公共 getter 和 setter)。 DataContract 可以作为操作的参数或返回值。

Windows Communication Foundation (WCF) 默认使用称为 Data Contract Serializer 的序列化引擎来序列化和反序列化数据(将其与 XML 相互转换),并且 XML 序列化(默认)不序列化只读属性。

有关更多信息,您可以阅读 MS Docs for Data Contracts:- https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-data-contracts

要了解数据合同的各种限制,请参考:-https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/types-supported-by-the-data-contract-serializer

解决方案:

无论如何。你想做什么?公开属性意味着您期望一些有状态的行为。 如果你打算在操作合同中使用这个属性,这似乎是,那么你必须使用公共 getter 和 setter 定义属性以便它可以被序列化。

正如previous answer 中所述的@Nikosi,您必须为您的 BaseDirectoryPath 属性定义公共设置器

【讨论】:

    【解决方案2】:

    基于示例的唯一区别是一个属性是readonly,而另一个属性可以修改。

    为了使类可序列化,考虑重构属性

    public class PathNames {
        private string _pathA = "Some Path";
        private string _pathB = "Another Path";
    
        public PathNames() {
            BaseDirectoryPath = Path.Combine(_pathA, _pathB);
        }
    
        public string BaseDirectoryPath { get; set; }
    }
    

    可以使用默认构造函数来设置属性的默认值

    或者只是在属性上有一个空的设置器

    public class PathNames {
        private string _pathA = "Some Path";
        private string _pathB = "Another Path";
    
        public string BaseDirectoryPath { 
            get {
                return Path.Combine(_pathA, _pathB);
            }
            set {
                //No OP
            }
        }
    }
    

    【讨论】:

    • 我已经尝试过您的解决方案,但它似乎仍然给我同样的问题。我创建了一个全新的类,其中只有一个带有 getset 的道具,但我仍然无法在对象浏览器中查看或访问它
    【解决方案3】:

    你可以看到creating a Custom ASP.NET Web Service。 您可能需要重新构建 Web 服务 ASP.Net 并将您的程序集添加到全局程序集缓存 (GAC)。

    希望对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 2020-01-18
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多