-
Notifications
You must be signed in to change notification settings - Fork 19
Could not load actions: class with EasyTcpAction doesn't have have parameterless constructor #43
Comments
Thanks for creating an issue! I found 1 problem in ActionsExample.cs, this is fixed Does this minimal example work? using System;
using System.Text;
using EasyTcp3;
using EasyTcp3.Actions;
namespace Test
{
class Program
{
static void Main(string[] args)
{
using var server = new EasyTcpActionServer();
server.ExecuteAction("Print", new Message(Encoding.UTF8.GetBytes("Success")));
Console.ReadKey();
}
[EasyTcpAction("Print")]
public void Print(Message message)
=> Console.WriteLine(message);
}
} Edit:
EasyTcp takes the calling assembly as default assembly, do this when actions are located in the executing assembly: using var server = new EasyTcpActionServer(assembly: Assembly.GetExecutingAssembly()); |
Could you provide the location of the call to the EasyTcpActionServer constructor and the location of the action methods? Also, could you try moving the class outside the other class? Could be that the instance can't be created using reflection because it is inside another class. |
The Console Application using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
SINCMultiplayer.AuthorizationExample.Start();
SINCMultiplayer.AuthorizationExample.Connect();
Console.ReadKey();
}
}
} The code inside the library, now outside of the other class but with the same error, if i check "Assembly.GetExecutingAssembly().FullName" it will give me the name of the right assembly. using System;
using System.Reflection;
using System.Threading.Tasks;
using EasyTcp3;
using EasyTcp3.Actions;
using EasyTcp3.Actions.ActionUtils;
using EasyTcp3.ClientUtils;
using EasyTcp3.Server;
using EasyTcp3.Server.ServerUtils;
namespace SINCMultiplayer
{
public class AuthorizationExample
{
private const ushort Port = 52512;
static EasyTcpActionServer server;
public static void Start()
{
server = new EasyTcpActionServer(assembly: Assembly.GetExecutingAssembly()).Start(Port);
}
/* Example login action
* Set userRole inside session
*/
[EasyTcpAction("Login")]
public void Login(Message message)
{
if (message.ToString() == "user")
message.Client.Session["UserRole"] = UserRole.User;
else if (message.ToString() == "admin")
message.Client.Session["UserRole"] = UserRole.Admin;
Console.WriteLine($"Authenticated {message}");
}
[EasyTcpAuthorization] // User does need to login before using this action
[EasyTcpAction("Print")]
public void UserOnlyThing(Message message) => Console.WriteLine(message);
[EasyTcpAuthorization(UserRole.Admin)] // User does need to be admin for this action
[EasyTcpAction("Clear")]
public void AdminOnlyThing() => Console.Clear();
[EasyTcpAuthorization]
[EasyTcpAction("Logout")]
public void Logout(Message message) => message.Client.Session.Remove("UserRole");
public static void Connect()
{
var client = new EasyTcpClient();
if (!client.Connect("127.0.0.1", Port)) return;
client.SendAction("Print", "This is ignored because the user is not logged in");
client.SendAction("Login", "user");
client.SendAction("Print", "Hello server, I am now logged in");
client.SendAction("Clear"); // Ignored by server
client.SendAction("Logout");
client.SendAction("Print", "This is ignored because user is logged out");
Console.ReadLine();
}
}
/* EasyTcpAuthorization,
* example filter attribute for authorization
*/
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class EasyTcpAuthorization : EasyTcpActionFilter
{
private readonly UserRole[] _allowedRoles;
/// <summary>
/// Accept any logged in user
/// </summary>
public EasyTcpAuthorization() : base() => _allowedRoles = new[] { UserRole.User, UserRole.Admin };
/// <summary>
/// Accept user with a specific role
/// </summary>
/// <param name="role">allowed roles</param>
public EasyTcpAuthorization(params UserRole[] role) : base() => _allowedRoles = role;
/// <summary>
/// Determines whether user has access to this action
/// </summary>
/// <param name="sender"></param>
/// <param name="message"></param>
/// <returns></returns>
public override bool HasAccess(object sender, ActionMessage message)
{
var hasRole = message.Client.Session.TryGetValue("UserRole", out object userRole);
if (!hasRole) return false;
if (_allowedRoles.Any(x => x == userRole as UserRole?)) return true;
else return false;
}
}
/* Enum with different roles */
public enum UserRole
{
User,
Admin
}
} If i put the same code inside the console application (the calling assembly) it works without problems using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using EasyTcp3;
using EasyTcp3.Actions;
using EasyTcp3.Actions.ActionUtils;
using EasyTcp3.ClientUtils;
using EasyTcp3.Server;
using EasyTcp3.Server.ServerUtils;
namespace TestConsole
{
public class AuthorizationExample
{
private const ushort Port = 52512;
static EasyTcpActionServer server;
public static void Start()
{
server = new EasyTcpActionServer().Start(Port);
}
/* Example login action
* Set userRole inside session
*/
[EasyTcpAction("Login")]
public void Login(Message message)
{
if (message.ToString() == "user")
message.Client.Session["UserRole"] = UserRole.User;
else if (message.ToString() == "admin")
message.Client.Session["UserRole"] = UserRole.Admin;
Console.WriteLine($"Authenticated {message}");
}
[EasyTcpAuthorization] // User does need to login before using this action
[EasyTcpAction("Print")]
public void UserOnlyThing(Message message) => Console.WriteLine(message);
[EasyTcpAuthorization(UserRole.Admin)] // User does need to be admin for this action
[EasyTcpAction("Clear")]
public void AdminOnlyThing() => Console.Clear();
[EasyTcpAuthorization]
[EasyTcpAction("Logout")]
public void Logout(Message message) => message.Client.Session.Remove("UserRole");
public static void Connect()
{
var client = new EasyTcpClient();
if (!client.Connect("127.0.0.1", Port)) return;
client.SendAction("Print", "This is ignored because the user is not logged in");
client.SendAction("Login", "user");
client.SendAction("Print", "Hello server, I am now logged in");
client.SendAction("Clear"); // Ignored by server
client.SendAction("Logout");
client.SendAction("Print", "This is ignored because user is logged out");
Console.ReadLine();
}
}
/* EasyTcpAuthorization,
* example filter attribute for authorization
*/
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class EasyTcpAuthorization : EasyTcpActionFilter
{
private readonly UserRole[] _allowedRoles;
/// <summary>
/// Accept any logged in user
/// </summary>
public EasyTcpAuthorization() => _allowedRoles = new[] { UserRole.User, UserRole.Admin };
/// <summary>
/// Accept user with a specific role
/// </summary>
/// <param name="role">allowed roles</param>
public EasyTcpAuthorization(params UserRole[] role) => _allowedRoles = role;
/// <summary>
/// Determines whether user has access to this action
/// </summary>
/// <param name="sender"></param>
/// <param name="message"></param>
/// <returns></returns>
public override bool HasAccess(object sender, ActionMessage message)
{
var hasRole = message.Client.Session.TryGetValue("UserRole", out object userRole);
if (!hasRole) return false;
if (_allowedRoles.Any(x => x == userRole as UserRole?)) return true;
else return false;
}
}
/* Enum with different roles */
public enum UserRole
{
User,
Admin
}
} |
No, that doesn't bring it back |
The examples
https://github.com/Job79/EasyTcp/blob/master/EasyTcp3/EasyTcp3.Examples/Actions/ActionsExample.cs
and
https://github.com/Job79/EasyTcp/blob/master/EasyTcp3/EasyTcp3.Examples/Actions/AuthorizationExample.cs
will both throw me this error:
I did copy the code from the examples 1:1 and added using EasyTcp3; as a using but I couldn't get it running
EasyTcp version: 3.6.3
EasyTcp.Actions version: 2.5.2
Net Framework: 4.7.2
Edit: This only happens if EasyTcp is called from inside a library.
The text was updated successfully, but these errors were encountered: