Skip to content

Commit 3e95666

Browse files
committed
Enhance method handling and add parameter conversion
- Modify `ITelegramUpdateHandler` to return nullable `MethodInfo` - Add null check and parameter count validation in `BotApp.cs` - Update `TextMessageHandler.cs` to handle nullable `_methodInfo` - Introduce `ObjectHelpers` for parameter type conversion
1 parent cbcb549 commit 3e95666

4 files changed

Lines changed: 82 additions & 11 deletions

File tree

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
using System.Reflection;
2-
using Telegram.Bot.Types;
32

43
namespace TelegramBot.Handlers
54
{
65
internal interface ITelegramUpdateHandler
76
{
8-
MethodInfo GetMethodInfo();
7+
MethodInfo? GetMethodInfo();
98
object[]? GetArguments();
109
}
1110
}

Sources/TelegramBot/BotApp.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,20 @@ private async Task HandleRequestAsync(ITelegramUpdateHandler handler, Update upd
201201
return;
202202
}
203203
var args = handler.GetArguments();
204-
MethodInfo method = handler.GetMethodInfo();
204+
MethodInfo? method = handler.GetMethodInfo();
205+
if (method == null)
206+
{
207+
_logger.LogWarning("Method not found for message: {Text}.", update.Message?.Text);
208+
return;
209+
}
205210
if (method.ReturnType != typeof(Task<IActionResult>) && method.ReturnType != typeof(IActionResult))
206211
{
207212
throw new InvalidOperationException("Invalid return type: " + method.ReturnType.Name);
208213
}
214+
if (method.GetParameters().Length != args?.Length)
215+
{
216+
throw new InvalidOperationException("Invalid arguments count: " + args?.Length);
217+
}
209218
BotControllerBase controller = (BotControllerBase)ActivatorUtilities.CreateInstance(_serviceProvider, method.DeclaringType);
210219
controller.Update = update;
211220
controller.User = user;

Sources/TelegramBot/Handlers/TextMessageHandler.cs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using System;
2-
using System.Reflection;
1+
using System.Reflection;
32
using Telegram.Bot.Types;
3+
using TelegramBot.Helpers;
44
using TelegramBot.Attributes;
55
using System.Collections.Generic;
66

@@ -9,12 +9,12 @@ namespace TelegramBot.Handlers
99
internal class TextMessageHandler : ITelegramUpdateHandler
1010
{
1111
private readonly List<object> _args;
12-
private readonly MethodInfo _methodInfo;
12+
private readonly MethodInfo? _methodInfo;
1313

1414
public TextMessageHandler(IReadOnlyCollection<MethodInfo> controllerMethods, Update update)
1515
{
1616
_args = new List<object>();
17-
_methodInfo = GetMethodInfo(controllerMethods, update) ?? throw new InvalidOperationException("Method not found for message " + update.Message?.Text);
17+
_methodInfo = GetMethodInfo(controllerMethods, update);
1818
}
1919

2020
private MethodInfo? GetMethodInfo(IReadOnlyCollection<MethodInfo> controllerMethods, Update update)
@@ -26,7 +26,16 @@ public TextMessageHandler(IReadOnlyCollection<MethodInfo> controllerMethods, Upd
2626
var message = update.Message;
2727
var parts = message.Text!.Split(' ');
2828
string command = parts[0];
29+
if (!command.StartsWith("/"))
30+
{
31+
return null;
32+
}
33+
if (parts.Length > 1)
34+
{
35+
_args.AddRange(parts[1..]);
36+
}
2937

38+
List<MethodInfo> methods = new List<MethodInfo>();
3039
foreach (var method in controllerMethods)
3140
{
3241
var attributes = method.GetCustomAttributes(typeof(TextCommandAttribute), false);
@@ -36,15 +45,30 @@ public TextMessageHandler(IReadOnlyCollection<MethodInfo> controllerMethods, Upd
3645
{
3746
if (botCommandAttribute.Command == command)
3847
{
39-
if (parts.Length == 2 && method.GetParameters().Length == 1)
48+
if (_args.Count == method.GetParameters().Length)
4049
{
41-
_args.Add(parts[1]);
50+
bool converted = ObjectHelpers.TryConvertParameters(method, _args.ToArray());
51+
if (converted)
52+
{
53+
methods.Add(method);
54+
}
4255
}
43-
return method;
4456
}
4557
}
4658
}
4759
}
60+
if (methods.Count == 1)
61+
{
62+
var args = _args.ToArray();
63+
ObjectHelpers.TryConvertParameters(methods[0], args);
64+
_args.Clear();
65+
_args.AddRange(args);
66+
return methods[0];
67+
}
68+
else if (methods.Count > 1)
69+
{
70+
throw new AmbiguousMatchException("Multiple methods found with the same command and arguments: " + command);
71+
}
4872
return null;
4973
}
5074

@@ -54,7 +78,7 @@ public TextMessageHandler(IReadOnlyCollection<MethodInfo> controllerMethods, Upd
5478
return _args.Count > 0 ? _args.ToArray() : null;
5579
}
5680

57-
public MethodInfo GetMethodInfo()
81+
public MethodInfo? GetMethodInfo()
5882
{
5983
return _methodInfo;
6084
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Reflection;
3+
using System.Collections.Generic;
4+
5+
namespace TelegramBot.Helpers
6+
{
7+
internal static class ObjectHelpers
8+
{
9+
internal static bool TryConvertParameters(MethodInfo method, object[] args)
10+
{
11+
List<object> newArgs = new List<object>(args.Length);
12+
var parameters = method.GetParameters();
13+
foreach (var parameter in parameters)
14+
{
15+
if (parameter.ParameterType.IsPrimitive || parameter.ParameterType == typeof(string))
16+
{
17+
try
18+
{
19+
var changedType = Convert.ChangeType(args[parameter.Position], parameter.ParameterType);
20+
newArgs.Add(changedType);
21+
}
22+
catch (Exception)
23+
{
24+
return false;
25+
}
26+
}
27+
else
28+
{
29+
return false;
30+
}
31+
}
32+
for (int i = 0; i < newArgs.Count; i++)
33+
{
34+
args[i] = newArgs[i];
35+
}
36+
return true;
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)