无法 post 到 AXL 端点
unable to post to AXL endpoint
我的目标是能够 post 并从使用基于 SOAP 的端点检索 API
我的项目结构
我用 WSDL 文件生成了一个客户端以 cucm 11.5 为目标,然后
我按照 github 上的示例创建了所有 classes 和接口,就像在 repo
上所做的那样
第三,我的解决方案由两个项目组成,一个 class 库和一个控制台项目,class 库包含从 WSDL 文件生成的客户端,控制台项目由 class 和与 class 库项目交互的接口
I have the following class to perform an operation
public class TestAxl
{
public void CreateUsers()
{
var axlClient = new AxlClient(new AxlClientConfiguration
{
Server = "Ip to the publish server",
User = "administrator",
Password = "password provided"
});
var addUserResult = axlClient.ExecuteAsync(async client =>
{
var userId = Guid.NewGuid().ToString();
var request = new AddUserReq
{
user = new XUser
{
userid = userId,
userIdentity = userId,
password = "P@ssw0rd",
firstName = "test",
lastName = "test"
}
};
var response = await client.addUserAsync(request);
return response.addUserResponse1.@return;
});
}
}
and i call it from the main class like so
class Program
{
static void Main(string[] args)
{
var letsDoSomeTesting = new TestAxl();
try
{
letsDoSomeTesting.CreateUsers();
}
catch (Exception e)
{
Console.WriteLine("The following is the exceeption from calling final class ", e.Message);
}
}
}
当我尝试 运行 控制台项目时,它以 0 启动和退出,
然后我回到 CUCM 沙箱环境,没有任何改变,可能是什么原因导致此操作无法正常工作
仅供参考:运行时 netCore 3.1
我能够得到一个示例项目,包括 AXL/addUser,在 Linux 上使用 DotNet Core 3.1:https://github.com/CiscoDevNet/axl-dotnet-samples
这是主要部分:
// Create a custom binding so we can allow the client to use cookies with AXL
BasicHttpsBinding binding = new BasicHttpsBinding();
binding.AllowCookies = true;
// Specify the CUCM AXL API location for the SOAP client
EndpointAddress address = new EndpointAddress( $"https://{ System.Environment.GetEnvironmentVariable( "CUCM_ADDRESS" ) }:8443/axl/" );
//Class generated from AXL WSDL
AXLPortClient client = new AXLPortClient( binding, address );
// To disable HTTPS certificate checking, uncomment the below lines
// NOT for production use!
// client.ChannelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
// {
// CertificateValidationMode = X509CertificateValidationMode.None,
// RevocationMode = X509RevocationMode.NoCheck
// };
// client.ChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
// client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
// Incantation to force alternate serializer reflection behaviour due to complexities in the AXL schema
// See https://github.com/dotnet/wcf/issues/2219
MethodInfo method = typeof( XmlSerializer ).GetMethod( "set_Mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static );
method.Invoke( null, new object[] { 1 } );
// Base64 encode AXL username/password for Basic Auth
var encodedUserPass = Convert.ToBase64String( Encoding.ASCII.GetBytes(
System.Environment.GetEnvironmentVariable( "CUCM_USERNAME" ) + ":" +
System.Environment.GetEnvironmentVariable( "CUCM_PASSWORD" )
) );
// Incantation to create and populate a Basic Auth HTTP header
// This must be done to force SoapCore to include the Authorization header on the first attempt
// rather than in challenge/response fashion
HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
requestProperty.Headers[ "Authorization" ] = "Basic " + encodedUserPass;
// Creating context block apparently allows attaching custom HTTP headers to the request
var scope = new OperationContextScope( client.InnerChannel );
OperationContext.Current.OutgoingMessageProperties[ HttpRequestMessageProperty.Name ] = requestProperty;
//Create the request object
AddUserReq addUserReq = new AddUserReq();
addUserReq.user = new XUser();
addUserReq.user.lastName = "TestUser";
addUserReq.user.userid = "testUser";
addUserReq.user.password = "Cisco!1234";
string userPkid = "";
//Try the addUser request
try
{
addUserResponse addUserResp = await client.addUserAsync( addUserReq );
userPkid = addUserResp.addUserResponse1.@return;
}
catch ( Exception ex )
{
Console.WriteLine( $"\nError: addUser: { ex.Message }" );
Environment.Exit( -1 );
}
一些注意事项:
SoapCore 尽可能生成具有默认值的元素,例如字符串元素为 nil。这会导致 <addUser>
出现问题,因为 <customerName>
元素应该只发送到 HCS CUCMs。在 运行 svcutil 能够解决它之前对 AXLSoap.xsd 进行修改:
sed -i 's/name=\"customerName\" nillable=\"true\"/name=\"customerName\" nillable=\"false\"/g' schema/AXLSoap.xsd
由于 CUCM 自签名证书的 HTTPS 认证验证,请求将失败,除非它安装到 OS CA 信任库或被禁用(请参阅代码中的注释部分以上)
需要以下奇怪的代码来避免发出请求时出现 "Compiling JScript/CSharp scripts is not supported" 错误(根据 here):
MethodInfo method = typeof( XmlSerializer ).GetMethod( "set_Mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static );
method.Invoke( null, new object[] { 1 } );
我的目标是能够 post 并从使用基于 SOAP 的端点检索 API
我的项目结构
我用 WSDL 文件生成了一个客户端以 cucm 11.5 为目标,然后
我按照 github 上的示例创建了所有 classes 和接口,就像在 repo
上所做的那样第三,我的解决方案由两个项目组成,一个 class 库和一个控制台项目,class 库包含从 WSDL 文件生成的客户端,控制台项目由 class 和与 class 库项目交互的接口
I have the following class to perform an operation
public class TestAxl
{
public void CreateUsers()
{
var axlClient = new AxlClient(new AxlClientConfiguration
{
Server = "Ip to the publish server",
User = "administrator",
Password = "password provided"
});
var addUserResult = axlClient.ExecuteAsync(async client =>
{
var userId = Guid.NewGuid().ToString();
var request = new AddUserReq
{
user = new XUser
{
userid = userId,
userIdentity = userId,
password = "P@ssw0rd",
firstName = "test",
lastName = "test"
}
};
var response = await client.addUserAsync(request);
return response.addUserResponse1.@return;
});
}
}
and i call it from the main class like so
class Program
{
static void Main(string[] args)
{
var letsDoSomeTesting = new TestAxl();
try
{
letsDoSomeTesting.CreateUsers();
}
catch (Exception e)
{
Console.WriteLine("The following is the exceeption from calling final class ", e.Message);
}
}
}
当我尝试 运行 控制台项目时,它以 0 启动和退出,
然后我回到 CUCM 沙箱环境,没有任何改变,可能是什么原因导致此操作无法正常工作
仅供参考:运行时 netCore 3.1
我能够得到一个示例项目,包括 AXL/addUser,在 Linux 上使用 DotNet Core 3.1:https://github.com/CiscoDevNet/axl-dotnet-samples
这是主要部分:
// Create a custom binding so we can allow the client to use cookies with AXL
BasicHttpsBinding binding = new BasicHttpsBinding();
binding.AllowCookies = true;
// Specify the CUCM AXL API location for the SOAP client
EndpointAddress address = new EndpointAddress( $"https://{ System.Environment.GetEnvironmentVariable( "CUCM_ADDRESS" ) }:8443/axl/" );
//Class generated from AXL WSDL
AXLPortClient client = new AXLPortClient( binding, address );
// To disable HTTPS certificate checking, uncomment the below lines
// NOT for production use!
// client.ChannelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
// {
// CertificateValidationMode = X509CertificateValidationMode.None,
// RevocationMode = X509RevocationMode.NoCheck
// };
// client.ChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
// client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
// Incantation to force alternate serializer reflection behaviour due to complexities in the AXL schema
// See https://github.com/dotnet/wcf/issues/2219
MethodInfo method = typeof( XmlSerializer ).GetMethod( "set_Mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static );
method.Invoke( null, new object[] { 1 } );
// Base64 encode AXL username/password for Basic Auth
var encodedUserPass = Convert.ToBase64String( Encoding.ASCII.GetBytes(
System.Environment.GetEnvironmentVariable( "CUCM_USERNAME" ) + ":" +
System.Environment.GetEnvironmentVariable( "CUCM_PASSWORD" )
) );
// Incantation to create and populate a Basic Auth HTTP header
// This must be done to force SoapCore to include the Authorization header on the first attempt
// rather than in challenge/response fashion
HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
requestProperty.Headers[ "Authorization" ] = "Basic " + encodedUserPass;
// Creating context block apparently allows attaching custom HTTP headers to the request
var scope = new OperationContextScope( client.InnerChannel );
OperationContext.Current.OutgoingMessageProperties[ HttpRequestMessageProperty.Name ] = requestProperty;
//Create the request object
AddUserReq addUserReq = new AddUserReq();
addUserReq.user = new XUser();
addUserReq.user.lastName = "TestUser";
addUserReq.user.userid = "testUser";
addUserReq.user.password = "Cisco!1234";
string userPkid = "";
//Try the addUser request
try
{
addUserResponse addUserResp = await client.addUserAsync( addUserReq );
userPkid = addUserResp.addUserResponse1.@return;
}
catch ( Exception ex )
{
Console.WriteLine( $"\nError: addUser: { ex.Message }" );
Environment.Exit( -1 );
}
一些注意事项:
SoapCore 尽可能生成具有默认值的元素,例如字符串元素为 nil。这会导致
<addUser>
出现问题,因为<customerName>
元素应该只发送到 HCS CUCMs。在 运行 svcutil 能够解决它之前对 AXLSoap.xsd 进行修改:sed -i 's/name=\"customerName\" nillable=\"true\"/name=\"customerName\" nillable=\"false\"/g' schema/AXLSoap.xsd
由于 CUCM 自签名证书的 HTTPS 认证验证,请求将失败,除非它安装到 OS CA 信任库或被禁用(请参阅代码中的注释部分以上)
需要以下奇怪的代码来避免发出请求时出现 "Compiling JScript/CSharp scripts is not supported" 错误(根据 here):
MethodInfo method = typeof( XmlSerializer ).GetMethod( "set_Mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static ); method.Invoke( null, new object[] { 1 } );