我正在创建一个Winamp插件,其功能是将通过HTTP播放的歌曲的详细信息发送到网页。
它的工作方式如下:触发了Winamp歌曲事件 - >检查新歌 - >使用PubNub(C#API)发布到网页。
到目前为止,我进入了一切都按预期工作的阶段,除了 PubNub代码,它没有序列化我要传递给JSON的对象。我继续在PubNub控制台中获取的只是{}
- 一个空的JSON对象。
项目结构的一些背景知识:
我正在使用Sharpamp这是一个自定义库,可以使用C#制作Winamp插件。我也在使用PubNub C# API。 gen_notifier_cs项目是Sharpamp创建的C ++插件包装器。 notifier_cs是我所有代码所在的位置。我假设其他两个项目是自我解释的。 我在notifier_cs中引用了PubNub API,并且在notifier_cs和PubNub API中都引用了Sharpamp。
因此,需要序列化的对象属于Sharpamp中定义的类Song
:
public class Song
{
public string Title { get; internal set; }
public string Artist { get; internal set; }
public string Album { get; internal set; }
public string Year { get; internal set; }
public bool HasMetadata { get; internal set; }
public string Filename { get; internal set; }
}
所以,假设我有一个带有歌曲数据的song
对象,我会去pubnub.publish("winamp_pipe", song);
发布它,PubNub会自动将数据序列化为JSON。但这不适用于我的解决方案。
为了测试它没有序列化的原因,我将该类复制到PubNub API中的example code file。 Visual Studio将类更改为此(请注意公共Song()方法):
public class Song
{
public Song() // VS added this method
{
return; // I added this otherwise it would not compile
}
public string Album { get; set; }
public string Artist { get; set; }
public string Filename { get; set; }
public bool HasMetadata { get; set; }
public string Title { get; set; }
public string Year { get; set; }
}
在同一个示例文件中,我启动了一个带有一些值的默认歌曲对象:
Song song = new Song();
song.Album = "albumname";
song.Artist = "artistname";
song.HasMetadata = true;
song.Title = "songtitle";
song.Year = "2012";
并发布了它:pubnub.publish("winamp_pipe", song);
并且它有效!我在PubNub频道中获得了JSON对象!
{"Album":"albumname","Artist":"artistname","Filename":null,"HasMetadata":true,"Title":"songtitle","Year":"2012"}
所以,我尝试用Sharpamp中定义的原始类替换“new”Song
类。我尝试在notifier_cs项目中添加另一个类定义,但是与Sharpamp中的那个相冲突,我必须依赖它。就我能想到的那样,我一直在尝试这么多东西。不用说没有人占上风。不过,我得到的只是一个空的JSON对象。
这是在 PubNub API 的发布方法中进行序列化的代码。我将提醒您,此代码适用于PubNub示例文件,但不适用于我的项目:
DataContractJsonSerializer serializer = new DataContractJsonSerializer(objectToSerialize.GetType());
serializer.WriteObject(ms, objectToSerialize);
ms.Position = 0;
using (StreamReader reader = new StreamReader(ms))
{
return reader.ReadToEnd();
}
我最后一天都拔了头发。我知道这篇文章很长,但我很感激你的意见。
答案 0 :(得分:1)
您已将数据存储在winamp_song
对象实例中。如果您尝试序列化winamp_song
对象实例,它将失败。如果您传入winamp_song
,则序列化将失败,因为实例具有非可序列化成员。最好的方法是创建一个您拥有和定义的Song class
。在Song class
中定义将通过PubNub传递的成员值。这样,您就可以直接填充发布给订阅者所需的值。
Song song = new Song();
song.Album = winamp_song.Album;
song.Artist = winamp_song.Artis;
song.HasMetadata = winamp_song.HasMetadata;
song.Title = winamp_song.Title;
song.Year = winamp_song.Year;
即使您的订阅者收到歌曲数据发布,您也可以接收反序列化数据,将值填充到新的Song class
实例中。
public class Song {
public Song() { return; }
public string Album { get; set; }
public string Artist { get; set; }
public string Filename { get; set; }
public bool HasMetadata { get; set; }
public string Title { get; set; }
public string Year { get; set; }
}
PubNub是与Winamp插件的已安装副本进行通信的最佳方法。
答案 1 :(得分:0)
好吧,我的“解决方案”,因为我只使用一个类(在Sharpamp库中定义的Song
类)来发布值,是手动构造一个JSON字符串:
pubnub.publish("winamp_pipe", "{\"Album\": \""+song.Album+"\",\"Artist\": \""+song.Artist+"\",\"HasMetadata\": \""+song.HasMetadata.ToString()+"\",\"Title\": \""+song.Title+"\",\"Year\": \""+song.Year+"\",\"Filename\": \""+song.Filename+"\"}");
它不是问题本身的解决方案,但它的目的是将信息作为JSON对象发布(只要您没有任何特殊字符可以破坏数据中的JSON结构)。
我不认为这是一个答案,因为它不是真正问题的解决方案,只是一个临时的解决方法......