无法在asp.net mvc中实现将tweet和图像一起发送到twitter
本文关键字:一起 图像 twitter tweet asp net mvc 实现 | 更新日期: 2023-09-27 18:28:00
我正在开发asp.net mvc。我正在尝试实现推特撰写推特机制文本和图像,并将其作为推特在推特中发送。我遵循了twitter API 1.1提供的文档。我遵循Twitterizer库来完成这一步,但它给我带来了错误,就像API版本1被弃用一样,尽管我使用的是最新的版本,它适用于除此之外的其他端点。所以我决定在我自己的上发出http请求
在我的情况下,我的表单中有文本区域和文件上传控件,比如
<form method="post" action="/Home/Upload" enctype="multipart/form-data">
<textarea id="message" name="message"></textarea>
<input type="file" name="file"/>
<input type="submit" value="submit"/>
</form>
之后,在我的动作中,我得到了用户选择的图像和他在我的操作中输入的文本。我已经将HttpPostedPostedFileBase转换为类似字节[]的
[HttpPost]
public ActionResult Upload(FormCollection coll, HttpPostedFileBase upfile)
{
byte[] data;
using (Stream inputStream = upfile.InputStream)
{
MemoryStream memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
data = memoryStream.ToArray();
}
HttpWebRequest webRequest = WebRequest.Create("https://api.twitter.com/1.1/statuses/update_with_media.json") as HttpWebRequest;
OAuthBase oauth = new OAuthBase();
string nonce = oauth.GenerateNonce();
string timeStamp = oauth.GenerateTimeStamp();
string normalizedUrl;
string normalizedRequestParameters;
string sig = oauth.GenerateSignature
(new System.Uri("https://api.twitter.com/1.1/statuses/update_with_media.json"), consumerKey, consumerSecret, userinfo.AuthToken,
userinfo.PayUserId, "POST", timeStamp, nonce,
OAuthBase.SignatureTypes.HMACSHA1, out normalizedUrl,
out normalizedRequestParameters);
string header = string.Format(@"OAuth oauth_consumer_key=""{0}"",oauth_signature_method=""{1}"",oauth_timestamp=""{2}"",oauth_nonce=""{3}"",oauth_version=""{4}"",oauth_token=""{5}"",oauth_signature=""{6}""",
HttpUtility.UrlEncode(consumerKey), HttpUtility.UrlEncode("HMAC-SHA1"), HttpUtility.UrlEncode(timeStamp), HttpUtility.UrlEncode(nonce), HttpUtility.UrlEncode("1.0"), HttpUtility.UrlEncode(userinfo.AuthToken), HttpUtility.UrlEncode(sig));
webRequest.Headers.Add("Authorization", header);
webRequest.Method = "POST";
webRequest.Credentials = CredentialCache.DefaultCredentials;
((HttpWebRequest)webRequest).UserAgent = ".NET Framework Example Client";
Dictionary<string, object> fieldsToInclude = new Dictionary<string, object>();
fieldsToInclude.Add("status", coll["new_message"]);
fieldsToInclude.Add("media[]", data);
string boundary = Guid.NewGuid().ToString().Replace("-", "");
string dataBoundary = "--------------------r4nd0m";
string contentType = "multipart/form-data; boundary=" + dataBoundary;
byte[] mydata = GetMultipartFormData(fieldsToInclude, contentType);
webRequest.ContentLength = mydata.Length;
webRequest.ContentType = contentType;
using (Stream requestStream = webRequest.GetRequestStream())
{
if (mydata != null)
{
requestStream.Write(mydata, 0, mydata.Length);
}
}
using (HttpWebResponse webResponse = webRequest.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
string retVal = reader.ReadToEnd();
}
return View();
}
在这里,我写了一种为图像和文本数据准备多部分形式数据结构的方法,比如
private byte[] GetMultipartFormData(Dictionary<string, object> fieldsToInclude, string boundary)
{
Stream formDataStream = new MemoryStream();
Encoding encoding = Encoding.UTF8;
foreach (KeyValuePair<string, object> kvp in fieldsToInclude)
{
if (kvp.Value.GetType() == typeof(byte[]))
{ //assume this to be a byte stream
byte[] data = (byte[])kvp.Value;
string header = string.Format("--{0}'r'nContent-Disposition: form-data; name='"{1}'"; filename='"{2}'";'r'nContent-Type: application/octet-stream'r'n'r'n",
boundary,
kvp.Key,
kvp.Key);
byte[] headerBytes = encoding.GetBytes(header);
formDataStream.Write(headerBytes, 0, headerBytes.Length);
formDataStream.Write(data, 0, data.Length);
}
else
{ //this is normal text data
string header = string.Format("--{0}'r'nContent-Disposition: form-data; name='"{1}'"'r'n'r'n{2}'r'n",
boundary,
kvp.Key,
kvp.Value);
byte[] headerBytes = encoding.GetBytes(header);
formDataStream.Write(headerBytes, 0, headerBytes.Length);
}
}
string footer = string.Format("'r'n--{0}--'r'n", boundary);
formDataStream.Write(encoding.GetBytes(footer), 0, footer.Length);
formDataStream.Position = 0;
byte[] returndata = new byte[formDataStream.Length];
formDataStream.Read(returndata, 0, returndata.Length);
formDataStream.Close();
return returndata;
}
这是我下面的方式,以http请求上传图片到twitter(又称为媒体上传)。但我收到错误500内部服务器错误。如果我的手术出错,请指导我。
我是Tweetinvi的开发者。上传就这么简单:
var imageBinary = File.ReadAllBytes("path");
var media = Upload.UploadImage(imageBinary);
var tweet = Tweet.PublishTweet("hello", new PublishTweetOptionalParameters
{
Medias = { media }
});
我认为这可以为你节省很多时间。
要上传的Tweetinvi文档:https://github.com/linvi/tweetinvi/wiki/Upload
您可以在LINQ to Twitter中使用TweetWithMedia方法来完成此操作,如下所示:
static void TweetWithMediaDemo(TwitterContext twitterCtx)
{
string status = "Testing TweetWithMedia #Linq2Twitter " + DateTime.Now.ToString(CultureInfo.InvariantCulture);
const bool possiblySensitive = false;
const decimal latitude = StatusExtensions.NoCoordinate; //37.78215m;
const decimal longitude = StatusExtensions.NoCoordinate; // -122.40060m;
const bool displayCoordinates = false;
const string replaceThisWithYourImageLocation = @"..'..'images'200xColor_2.png";
var mediaItems =
new List<Media>
{
new Media
{
Data = Utilities.GetFileBytes(replaceThisWithYourImageLocation),
FileName = "200xColor_2.png",
ContentType = MediaContentType.Png
}
};
Status tweet = twitterCtx.TweetWithMedia(
status, possiblySensitive, latitude, longitude,
null, displayCoordinates, mediaItems, null);
Console.WriteLine("Media item sent - Tweet Text: " + tweet.Text);
}
最后我找到了方法,即Twitterizer类库中存在的问题。众所周知,Twitter API弃用Twitter API 1.0,因此Twitterizer库根据Twitter API 1.1更新了所有Twitter API端点,但没有更新update_status_media端点。所以我无法使用它。我从github获得了Twitterizer2库源代码。我已经检查了update_status_media端点方法并修复了这个问题。需要在中进行更改
Twitterizer2/Methods/Tweets/UpdateWithmediaCommand.cs文件行号87更改this.OptionalProperties.APIBaseAddress="https://upload.twitter.com/1/";到this.OptionalProperties.APIBaseAddress="https://api.twitter.com/1.1/";此行。这很好用。在这里,我看到了Twitter API 1.1文档中的行:
重要信息:在API v1.1中,您现在使用API.twitter.com作为域,而不是upload.twitter.com.我们强烈建议使用SSL作为此方法。
希望这些信息对所有人都有帮助。
我们可以通过将图像作为流传递给SendTweetWithMedia()方法来共享图像。为了将图像作为流发送,我们需要对其进行转换。
private void sharetwitter ()
{
var oauth_consumer_key = "your API key";
var oauth_consumer_secret = "Your API secret key";
string token = "access token";
string tokenSecret = "access token secret ";
var post = db.Posts.Where(p => p.PostId ==id).FirstOrDefault();
StringBuilder str = new StringBuilder();
str.AppendLine(post.Title.Trim());
str.AppendLine("learn .net a lot of helpful programming stuffs.");
var service = new TweetSharp.TwitterService(oauth_consumer_key,oauth_consumer_secret);
service.AuthenticateWith(token, tokenSecret);
string url = "http://www.infinetsoft.com/Images/logoinfi.png";
service.SendTweetWithMedia(new SendTweetWithMediaOptions
{
Status = str.ToString(),
Images = new Dictionary<string, Stream> { { "infinetsoft", urltostream(url) } }
});
TempData["SuccessMessage"] = "tweeted success";
}
在这里我找到了更多细节的解决方案http://www.infinetsoft.com/Post/How-to-share-image-to-twitter-post-using-asp-net-MVC/1236#.V0Lj1DV97cs