【问题标题】:How to access custom attributes defined in WCF service using C#?如何使用 C# 访问 WCF 服务中定义的自定义属性?
【发布时间】:2011-01-05 18:01:11
【问题描述】:

第一个问题是,如何获取存储在变量中的对象的类型?通常我们会这样做:

Type t = typeof(ClassName); //if I know the class

但是,我该怎么说呢:

Type t = typeof(varClassName); //if the class name is stored in a variable

第二个问题,更广泛的情况是,我有一个 WCF 服务,其中包含一个 DataContract 类,比如“MyClass”,并且我已经为它定义了一个名为“MyAttribute”的自定义属性。有一种方法说“GetDataUsingDataContract”,其参数类型为 MyClass。现在在客户端,我调用 Web 服务。我使用 MethodInfo 和 ParameterInfo 类来获取相关方法的参数。但是如何访问实际上是类 Myclass 的方法参数的属性?这是我尝试过的代码:

MyService.Service1Client client = new MyService.Service1Client();
Type t = typeof(MyService.Service1Client);
MethodInfo members = t.GetMethod("GetDataUsingDataContract");
ParameterInfo[] parameters = members.GetParameters();
foreach (var parameter in parameters)
{
     MemberInfo mi = parameter.ParameterType; //Not sure if this the way
     object[] attributes;
     attributes = mi.GetCustomAttributes(true);
}

上面的代码没有检索到自定义属性“MyAttribute”。我在同一个项目中定义的类中尝试了这个概念并且它有效。请帮忙!

【问题讨论】:

    标签: wcf custom-attributes typeof


    【解决方案1】:

    但是,我该怎么说: 类型 t = typeof(varClassName); //如果类名存储在变量中

    试试

    Type.GetType("varClassName", false, true);
    

    关于你的第二个问题:

    上面的代码没有检索到我 自定义属性“MyAttribute”。我 在课堂上尝试了这个概念 在同一个项目中定义并且它 作品。请帮忙!

    只是猜测,我不确定属性是否默认暴露给客户端。我认为这与不受信任的程序集相同。某些属性是敏感信息。看到这个:

    http://blogs.msdn.com/b/haibo_luo/archive/2006/02/21/536470.aspx

    但是您可以尝试将服务项目类型链接到您的应用程序,方法是首先在您的客户端项目中引用服务程序集,然后转到您的服务引用 ->“配置服务引用”并选择“在所有引用的程序集中重用类型”。我不确定这个选项是否会影响服务接口类,但我经常将它与我的域对象一起使用。值得一试。

    【讨论】:

    • 在生产中,我实际上是使用 URI (http://.../xyzService.svc) 动态(动态)创建代理。我没有服务项目。这是第三方(另一组)提供的服务。那样的话,我该如何配置呢?
    【解决方案2】:
     Type mi = parameter.ParameterType; //Not sure if this the way
     object[] attributes;
     attributes = mi.GetCustomAttributes(true);
    

    确保您的代理类了解属性

    希望这会有所帮助

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.ServiceModel;
    using System.Runtime.Serialization;
    using System.Reflection;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                StartService();
            }
    
            string url = "http://localhost:234/MyService/";
            private void StartClient()
            {
                IMyService myService = ChannelFactory<IMyService>.CreateChannel(new BasicHttpBinding(), new EndpointAddress(url));
                Type t = typeof(IMyService);
                MethodInfo members = t.GetMethod("MyMethod");
                ParameterInfo[] parameters = members.GetParameters();
                foreach (var parameter in parameters)
                {
                    Type mi = parameter.ParameterType;
                    object[] attributes;
                    attributes = mi.GetCustomAttributes(true);
                }
            }
    
            private void StartService()
            {
                ServiceHost host = new ServiceHost(typeof(MyService), new Uri(url));
                host.AddServiceEndpoint(typeof(IMyService), new BasicHttpBinding(), "");
                host.Open();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                StartClient();
            }
        }
    
        [AttributeUsage(AttributeTargets.Interface)]
        public class MyAttrib : Attribute
        {
        }
    
        [MyAttrib]
        public interface IMyContract
        {
            string Name { get; set; }
        }
    
        [DataContract]
        public class MyContract : IMyContract
        {
            [DataMember]
            public string Name { get; set; }
        }
    
        [ServiceContract]
        public interface IMyService
        {
            [OperationContract]
            bool MyMethod(IMyContract dummy);
        }
    
        [ServiceBehavior(UseSynchronizationContext = false)]
        public class MyService : IMyService
        {
            public bool MyMethod(IMyContract dummy)
            {
                return true;
            }
        }
    }
    

    【讨论】:

    • 如何确保代理类有这样的知识。请参阅我刚刚推测的答案。如果我错了,请解释,因为我对正确答案感兴趣。谢谢!
    • 我也有同样的问题,如何保证代理类有属性知识?
    • 所有属性必须在客户端引用的库中,并在生成的代理类上手动添加属性。更好的方法是对数据合约使用接口并在接口上使用属性
    • 你能不能给我举个例子。我不确定我是否理解正确。我有一个接口,一个继承 Attribute 类的类和用自定义属性装饰的 MyCompositeType 类。在界面中,我有一个方法,该方法具有 MyCompositeType 类型的参数。我如何使用您的接口解决方案来完成这项工作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多