【问题标题】:Working with nested .NET enums in AX 2009在 AX 2009 中使用嵌套的 .NET 枚举
【发布时间】:2017-06-22 13:30:46
【问题描述】:

我有一个带有 TestService.TestServiceWebClient 类的 DLL。
它的构造函数有两个参数,一个是string类型,另一个是TestService.TestServiceWebClient.MODE类型,它是一个枚举。

在 C# 中,我可以通过下面的代码轻松使用它。

string secret;
secret = "asdfasdf";

TestService.TestServiceWebClient test = new TestService.TestServiceWebClient(secret, TestService.TestServiceWebClient.MODE.TEST);

test.setGroupForCustomer("test@foo.com", "12345", "TestService.TestServiceWebClient.CUST_GROUPS.MILITARY);

在 AX 中,我遇到了一些麻烦。我知道正确引用了 DLL,因为我在创建类的实例时看到了参数,但是我收到了诸如

之类的错误

TestService 类不包含此功能

当我使用关键字new时:

TestService test;
;
test = new TestService.TestServiceWebClient(secret, "");

我也试过了……

TestService.TestServiceWebClient test;
;
test = new TestService.TestServiceWebClient(secret, "");

第二个参数不是string,所以当我尝试添加枚举时,我得到了

枚举不存在...

TestService test;
;
test = new TestService.TestServiceWebClient(secret, TestService.TestServiceWebClient.MODE::TEST);

我是否需要在 AX 中创建一个可以映射到我的 DLL 中的枚举的枚举?

C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Specialized;

namespace ProductService
{
    public class TestWebClient
    {
        public enum CUST_GROUPS
        {
            NOT_LOGGED_IN,
            GENERAL,
            WHOLESALE,
            RETAILER,
            TEST_REVIEWS,
            COTM_DISCOUNT,
            MILITARY,
            FIRST_RESPONDER
        };

        public enum MODE
        {
            DEV,
            TEST,
            PROD
        }
        public static int COTM_GROUP_ID = 5;
        public static int GENERAL_GROUP_ID = 1;

        private string presharedSecret;

        private string BASE_URL;

        private static string destinationPathPut = "/path";
        private static string destinationPathGet = "/pathgroup";
        public TestWebClient(String presharedSecret, MODE mode)
        {
            this.presharedSecret = presharedSecret;
            switch (mode)
            {
                case MODE.DEV:
                    BASE_URL = "http://dev";
                    break;
                case MODE.TEST:
                    BASE_URL = "http://test";
                    break;
                case MODE.PROD:
                    BASE_URL = "https://prod";
                    break;
            }
        }

        public bool setGroupForCustomer(string customerEmail, string customerId, CUST_GROUPS selectedGroup)
        {
            WebClient client = new WebClient();
            try
            {
                NameValueCollection requestParams = new NameValueCollection();
                requestParams.Add("customer_id", customerId);
                requestParams.Add("email", customerEmail);
                requestParams.Add("group_id", ((int)selectedGroup).ToString());
                requestParams.Add("signature", Util.sha1Hash(customerId.ToString() + ((int)selectedGroup).ToString() + customerEmail + presharedSecret));
                byte[] response = client.UploadValues(BASE_URL + "/" + destinationPathPut,
                    requestParams
                );
                string result = System.Text.Encoding.UTF8.GetString(response);
            }
            catch (Exception e)
            {
                return false;
            }
            finally
            {
                client.Dispose();
            }
            return true;
        }

        public bool isInGroup(string customerEmail, string customerId, CUST_GROUPS selectedGroup)
        {
            WebClient client = new WebClient();
            NameValueCollection requestParams = new NameValueCollection();
            requestParams.Add("customer_id", customerId);
            requestParams.Add("email", customerEmail);
            requestParams.Add("group_id", ((int)selectedGroup).ToString());
            requestParams.Add("signature", Util.sha1Hash(customerId.ToString() + ((int)selectedGroup).ToString() + customerEmail + presharedSecret));
            byte[] response = client.UploadValues(BASE_URL + "/" + destinationPathGet,
                 requestParams
            );
            string result = System.Text.Encoding.UTF8.GetString(response);
            client.Dispose();
            System.Diagnostics.Debug.WriteLine(result);
            return result.Equals("true");
        }
    }
}

【问题讨论】:

    标签: .net axapta dynamics-ax-2009


    【解决方案1】:

    在 DynamicsAX 2009 中使用嵌套的 .NET 枚举有点糟糕 - 如果您可以控制程序集的源并且可以在不影响其他用户的情况下更改它,我建议您将其提升到与您的类相同的级别.另一种方法是编写代理方法或类,以便为您构建对象。

    话虽如此,有一种方法可以使用反射来处理它们。
    下面应该让您了解如何基于同样嵌套的框架枚举System.Environment.SpecialFolder 进行操作。

    static void NestedEnumDemo1(Args _args)
    {
        System.Type classType;
        System.Type enumType;
        System.Enum enumValue;
        System.Reflection.MethodInfo methodInfo;
        System.Object[] methodArgs;
        System.String specialFolderPath;
        str msg;
        ;
    
        classType = System.Type::GetType('System.Environment');
        enumType = System.Type::GetType('System.Environment+SpecialFolder');
        enumValue = System.Enum::Parse(enumType, 'System');
        methodInfo = classType.GetMethod('GetFolderPath');
        methodArgs = new System.Object[1]();
        methodArgs.SetValue(enumValue, 0);
        specialFolderPath = methodInfo.Invoke(null, methodArgs);
        msg = specialFolderPath;
        info(msg);
    }
    

    因此,对于您的情况,它可能看起来与此类似,尽管我无法测试它,因为我没有您的程序集,但它至少应该为您指明正确的方向:

    static void NestedEnumDemo2(Args _args)
    {
        System.Type classType;
        System.Type enumType;
        System.Enum enumValue;
    
        System.Type[] constructorParmTypes;
        System.Reflection.ConstructorInfo constructorInfo;
    
        System.String secret;
        System.Object[] constructorArgs;
        System.Object object;
        TestService.TestServiceWebClient test;
        ;
    
        classType = System.Type::GetType('TestService.TestServiceWebClient');
        enumType = System.Type::GetType('TestService.TestServiceWebClient+MODE');
        enumValue = System.Enum::Parse(enumType, 'TEST');
    
        constructorParmTypes = new System.Type[2]();
        constructorParmTypes.SetValue(System.Type::GetType('System.String'), 0);
        constructorParmTypes.SetValue(enumType, 1);
        constructorInfo = classType.GetConstructor(constructorParmTypes);
    
        secret = 'xxxxx';
        constructorArgs = new System.Object[2]();
        constructorArgs.SetValue(secret, 0);
        constructorArgs.SetValue(enumValue, 1);
        object = constructorInfo.Invoke(constructorArgs);
        test = object;
        // ...
    }
    

    希望对你有帮助

    【讨论】:

    • 谢谢。我们的“VAR”有一些类似的代码。我会试试你的。
    • 你有机会看吗?
    • 抱歉耽搁了……我被拖到其他项目上了。我今天回来了。
    • 我用 C# 代码更新了我的问题。当我使用它时; enumType = System.Type::GetType('ProductService.TestWebClient+MODE');它打印“类”。不应该是“枚举”吗?另外,当我添加时, enumValue = System.Enum::Parse(enumType, 'TEST');我收到“ClrObject 静态方法调用错误”。
    • 我没有取得太大的成功......也许我应该将枚举更改为字符串,以便我可以从 AX 传递它们。 @DAXaholic
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-12
    相关资源
    最近更新 更多