I’m developing a Telegram bot in C# but have difficulty with implementing Message
type. According to API documentation, chat
field can be either of type User
or of type GroupChat
. How do I implement that in C#?
So far I could only come up with following code using Newtonsoft.Json
:
public class Update {
....
[JsonProperty("chat")]
public User chat { get; set; }
[JsonProperty("chat")]
public GroupChat group_chat { get; set; }
....
}
But it doesn’t work with my WebAPI 2 controller method since I deserialize Message
using FromBody
attribute:
public async Task<HttpResponseMessage> Post(string token, [FromBody] Update update)
(type Update
has a field message
of type Message
)
Is there any better way to implement Message
type?
3
Answers
Since you are supposed to handle seemingly two completely different objects in one field I don’t think you can use strongly-typed objects but you can use a dynamic type for the chat field such as
Then you can access the variables and check if they are null or not to understand if it’s a user or a group chat:
I have faced this issue in Java as well. As both C# and Java are strong typed languages, my issue was similar.
I solved this by creating a generic
Chat
class. ThisChat
class contains the properties fromUser
as well as fromGroupChat
. The class also has the methodsisUser()
,isGroupChat()
,asUser()
andasGroupChat()
.I have to admit I have no knowledge of C#, so I can not write an example in that language for you, but here is the body of the
Chat
class, in Java:It’s quite verbose and adds duplicate code, so if anyone has any additions, I’d like to hear them as well.
You could build your
Message
type as an interface (IMessage
), and then implement it withGroupMessage
andUserMessage
classes.But what I would really do is handle this at a higher level. Looking at the docs here, rather than a complex object that can handle all of this I would think in terms of sending or receiving a message. Then I would think of all of the actions you might want to do when receiving a message. From there I would have an object that can raise an event for each of those actions. When you receive data (don’t think of it as a message), you parse the data and perhaps raise several events from what was one Telegram message object. Some of those events may require class definitions for the data needed by the event, but now we’re talking something that’s much narrower in scope; a better fit for the Single Responsibility Principle.
Going the other direction (sending data rather than receiving), the object would have methods for the different kinds of things you might do when sending data. Some of those methods may require classes for the data needed. When possible, use the same classes you did for the receiving events. It might even be just one
Send()
method with many overloads.