我正在用C#开发一个Telegram机器人,但是在实现Message
类型时遇到了困难。根据{{3}},chat
字段可以是User
类型,也可以是GroupChat
类型。我如何在C#中实现它?
到目前为止,我只能使用Newtonsoft.Json
:
public class Update {
....
[JsonProperty("chat")]
public User chat { get; set; }
[JsonProperty("chat")]
public GroupChat group_chat { get; set; }
....
}
但它不适用于我的WebAPI 2控制器方法,因为我使用Message
属性反序列化FromBody
:
public async Task<HttpResponseMessage> Post(string token, [FromBody] Update update)
(类型Update
的字段message
类型为Message
)
有没有更好的方法来实现Message
类型?
答案 0 :(得分:2)
由于您应该在一个字段中处理看似两个完全不同的对象,我不认为您可以使用强类型对象,但您可以在聊天字段中使用动态类型,例如
public class Telegram
{
public int message_id { get; set; }
public dynamic chat { get; set; }
}
然后,您可以访问变量并检查它们是否为空,以了解它是用户还是群组聊天:
static void Main(string[] args)
{
string json = @"{ ""chat"": { ""id"": 1, ""first_name"": ""my_first_name"", ""last_name"": ""my_last_name"", ""username"": ""my_username"" }, ""message_id"": 123 }";
var telegram = Newtonsoft.Json.JsonConvert.DeserializeObject<Telegram>(json);
string name = telegram.chat.first_name; // name = my_first_name
string title = telegram.chat.title; // title = null
}
答案 1 :(得分:0)
我也在Java中遇到过这个问题。由于C#和Java都是强类型语言,我的问题类似。
我通过创建一个通用的Chat
类来解决这个问题。此Chat
类包含User
以及GroupChat
中的属性。该课程还包含方法isUser()
,isGroupChat()
,asUser()
和asGroupChat()
。
我必须承认我不了解C#,所以我不能为你编写那种语言的例子,但这里是Chat
类的主体,用Java:
@SerializedName("id")
private int id;
@SerializedName("first_name")
private String firstName;
@SerializedName("last_name")
private String lastName;
@SerializedName("username")
private String username;
@SerializedName("title")
private String title;
public boolean isUser() {
return title == null;
}
public boolean isGroupChat() {
return !isUser();
}
public User asUser() {
return new User(id, firstName, username, lastName);
}
public GroupChat asGroupChat() {
return new GroupChat(id, title);
}
它非常冗长并且添加了重复的代码,所以如果有人有任何补充,我也希望听到它们。
答案 2 :(得分:0)
您可以将Message
类型构建为界面(IMessage
),然后使用GroupMessage
和UserMessage
类来实现它。
interface IMessage
{
int id;
//...
object chat {get;}
}
public class GroupMessage : IMessage
{
public int id;
public GroupChat group;
public object chat {get {return group;} }
}
public class UserMessage : IMessage
{
public int id;
public User user;
public object chat {get {return user;} }
}
但我真正要做的是在更高的层次处理这个问题。看一下这里的文档,而不是一个可以处理所有这些的复杂对象,我会考虑发送或接收一条消息。然后我会想到您在收到邮件时可能想要做的所有操作。从那里我将有一个对象可以为每个动作引发事件。当您收到数据(不要将其视为消息)时,您解析数据并可能从一个Telegram消息对象中引发多个事件。其中一些事件可能需要事件所需数据的类定义,但现在我们谈论的范围要窄得多;更适合单一责任原则。
走向另一个方向(发送数据而不是接收),该对象将具有您在发送数据时可能执行的各种操作的方法。其中一些方法可能需要所需数据的类。如果可能,请使用您为接收事件所执行的相同类。它甚至可能只是一个带有很多重载的Send()
方法。