• 締切済み

フォト蔵へアップロードできません(C#)

フォト蔵へアップロードするとエラー400が出てしまいます。 何が原因なのでしょうか?原因を教えてください。 以下コード //フォト蔵へのアップロード(注意動きません)// //送信するファイルのパス filePath="C:\\Users\\Public\\Pictures\\Sample Pictures\\test.jpg"; //送信先のURL string url1 = "http://api.photozou.jp/rest/photo_add"; //文字コード System.Text.Encoding enc = System.Text.Encoding.GetEncoding("UTF-8"); //WebRequestの作成 System.Net.HttpWebRequest req = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(url1); //メソッドにPOSTを指定 req.Method = "POST"; //ベーシック認証宣言、アカウントとパスワード req.PreAuthenticate = true; NetworkCredential network = new NetworkCredential("mailaddress@hoge.com", "password"); req.Credentials = network; //ヘッダを設定 req.Headers.Add("album_id", "1234567"); //ContentTypeを設定 req.ContentType = "image/jpeg"; //POST送信するデータを作成 System.IO.FileStream fs = new System.IO.FileStream( filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read); //POST送信するデータの長さを指定 req.ContentLength = fs.Length; //データをPOST送信するためのStreamを取得 System.IO.Stream reqStream = req.GetRequestStream(); //ファイルの内容を送信 byte[] readData = new byte[0x1000]; int readSize = 0; while (true) { readSize = fs.Read(readData, 0, readData.Length); if (readSize == 0) break; reqStream.Write(readData, 0, readSize); } fs.Close(); reqStream.Close(); //サーバーからの応答を受信するためのWebResponseを取得 System.Net.HttpWebResponse res = (System.Net.HttpWebResponse) req.GetResponse(); //応答データを受信するためのStreamを取得 System.IO.Stream resStream = res.GetResponseStream(); //受信 System.IO.StreamReader sr = new System.IO.StreamReader(resStream, enc); //閉じる sr.Close();

みんなの回答

回答No.1

/* 役に立たない雑多なメモ: *一応俺の環境ではmultipart/form-dataを使用することで、できるようになった。 ドキュメントの記述内容から推測したけど、正直チュートリアル的なしっかりサンプルを出してほしい… * ユーザー名・パスワード・ローカルマシン上の画像ファイルの位置・画像ファイルの形式・album_idの値・MIMEの画像のContent-Dispositionのfilenameパラメータに与えるファイル名(なんか付けないと400が返ってきた)は適宜置き換えてください。 ** album_idは (特定のアルバムを見たときのURIが http://photozou.jp/photo/list/1234567/4321098 みたいになっている。最後の4321098でわかる。) * Flushを埋め込む必要があるかどうかは知らないですが、一応念のため。意味ないかも。 * MIMEのRFCを読んだわけじゃないので最後 --AAAAA--というふうな形式にしなければならないかは調べていません。 * 画像データ中に"--AAAAA"と同じバイト列が含まれるとそれがboundary(デリミタ)とみなされたりすることあるんだろうか? *ユーザー認証に失敗したときは401が返ってきた。 *最初WireSharkで参考にしようと思ってオフィシャルアプリの「貼る蔵3」をインストールするも、フォト蔵のFAQにあるようにWindows Firewallに阻まれてアクセス出来なくて嵌ってた。いちおうファイアーウォール側では未知のアプリは通知するようチェックを入れているつもりなのだが通知、特になかったような。うーむ。 *質問文でFileStream.Readで提示されている、「提供できるわけじゃないんで分からないんで、指定したデータ長よりも短いデータしか読み込まれないかもしれない」ケースは俺の環境では怒らなかったので調査はしてない。心配なら質問文の通りにコードを書いてもいいと思う。ネットワークなんかじゃ、全データがちょっとずつしかこないことは起こりやすいんだろうけど。 */ using System; using System.IO; using System.Net; namespace TEST5 { class MainClass { public static void Main (string[] args) { String boundary = "AAAAA"; System.Uri uri = new System.Uri("http://api.photozou.jp/rest/photo_add"); System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri); req.Method = "POST"; req.KeepAlive = true; req.PreAuthenticate = true; NetworkCredential network = new NetworkCredential("himajin10****@gmail.com", "example"); req.Credentials = network; // ====================================== req.ContentType = "multipart/form-data;boundary=" + boundary; Stream s = req.GetRequestStream(); StreamWriter sw = new StreamWriter(s,System.Text.Encoding.ASCII); sw.NewLine = "\r\n"; sw.WriteLine("--" + boundary); // =============================================== sw.WriteLine("Content-Disposition:form-data;name=\"photo\";filename=\"ccd.png\""); sw.WriteLine("Content-Type:image/png"); sw.WriteLine("Content-Transfer-Encoding: binary"); sw.WriteLine(); sw.Flush(); FileStream fs = new FileStream("D:\\test\\aaa.png",System.IO.FileMode.Open); byte[] bytearray = new byte[fs.Length]; fs.Read(bytearray,0,Convert.ToInt32(fs.Length)); fs.Close(); s.Write(bytearray,0,bytearray.Length); s.Flush(); sw.WriteLine(); sw.Flush(); sw.WriteLine("--" + boundary); sw.Flush(); // ================================================= sw.WriteLine("Content-Disposition:form-data;name=\"album_id\""); sw.WriteLine(); sw.WriteLine("4235010"); sw.Flush(); // =================================================== sw.Write("--" + boundary + "--"); sw.Close(); s.Close(); System.IO.StreamReader sr = new System.IO.StreamReader(req.GetResponse().GetResponseStream(), System.Text.Encoding.UTF8); System.Console.WriteLine(sr.ReadToEnd()); } } }

関連するQ&A

  • [C#]FTPでの複数のファイルのアップロード

    ネットで調べたところ1つのファイルであれば、 下記の記述でアップロードできることがわかったのですが、 別々のフォルダにあるにファイルを複数同時にアップロードするプログラムがわかりません。 どなたかご教示ください。よろしくお願いいたします。 using System; using System.Net; using System.IO; class FtpWebPut {  static void Main()  {   string uri = "ftp://servername/Upload/secret.png";   string myFile = "tmp.png";   WebRequest req = WebRequest.Create(uri);   req.Credentials = new NetworkCredential("user01", "mypassword");   req.Method = WebRequestMethods.Ftp.UploadFile;   using (Stream st = req.GetRequestStream())   using (FileStream fs = new FileStream(myFile, FileMode.Open))   {    Byte[] buf = new Byte[1024];    int count = 0;    do    {     count = fs.Read(buf, 0, buf.Length);     st.Write(buf, 0, count);    }    while (count != 0);   }  } }

  • C#でストリームの保存の仕方

    以下のコードのストリームstの保存を行いたいのですが、Streamのインスタンスをnewで作れないので どのようにすればよいでしょうか。お願いします。 HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create("http://www.***.co.jp"); HttpWebResponse webres = (HttpWebResponse)webreq.GetResponse(); Stream st = webres.GetResponseStream();

  • VB2003でファイルのダウンロードについて教えて

    Dim req As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest) Dim res As WebResponse = req.GetResponse() Dim resStream As Stream = res.GetResponseStream() Dim fs As New System.IO.FileStream(SaveName, FileMode.Create, FileAccess.Write) Dim b As Integer While True b = resStream.ReadByte() If b = -1 Then Exit While fs.WriteByte(Convert.ToByte(b)) End While VB.NET2003ですが上記の方法でファイルをダウンロードしているのですが、 ブラウザで表示して転送される場合は30秒ほどなのですが、 この方法でダウンロードすると130秒くらいかかってしまいます。 ディスクに書き込む動作が足を引っ張っているのかと思って 下から2行目を消して計測してみたのですがそれでも10秒ほどしか短縮しませんでした。 タスクマネージャーで確認してもCPUリソースが50をずっと超えているのですが ブラウザなどでダウンロードする時のように高速でCPUに負担をかけずにダウンロードするには どんな方法でやれば良いでしょうか? よろしくお願い致します。

  • レスポンスが全く返ってこない

    C# の HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strURL); でログインページにpostしてログオンしていますが、 たいていのページは HttpWebRequest でレスポンスが返ってくるのですが、 レスポンスがなし\"\"の場合があります。 ContentTypeもapplication/x-www-form-urlencoded で送信してるし、 たいていのページはこれでいけています。(ちょっと自身アリ) レスポンスのStreamを全く返さないページってありうるのでしょうか? (ブラウザではログインできます) (レスポンスのパラメータをチェックしましたが、リダイレクトらしきURLもなし) それともpost方法自体他の方法がある?? 漠然とした質問ですいません。

  • FTP接続の例外処理

    vb.netで開発しています。 以下のソースはFTPでtxtファイルを外部ホスティングサーバーにアップロードしている箇所です。 Private Function UpRoad(ByVal Flnm As String) As Boolean Dim s As Integer 'Err数 Dim Int_Err As Integer = 0 For s = 0 To 2 ' アップロードするファイル() Dim upFile As String = "C:\HighwayMail\SendData\Data\" & Flnm 'アップロード先のURI Dim u As New Uri(ftpad & "/data/" & Flnm) 'FtpWebRequestの作成 Dim ftpReq As System.Net.FtpWebRequest = _ CType(System.Net.WebRequest.Create(u), System.Net.FtpWebRequest) 'ログインユーザー名とパスワードを設定 ftpReq.Credentials = New System.Net.NetworkCredential(usernm, pass) 'MethodにWebRequestMethods.Ftp.UploadFile("STOR")を設定 ftpReq.Method = System.Net.WebRequestMethods.Ftp.UploadFile '要求の完了後に接続を閉じる ftpReq.KeepAlive = False 'ASCIIモードで転送する ftpReq.UseBinary = False 'PASVモードを無効にする ftpReq.UsePassive = False Try 'ファイルをアップロードするためのStreamを取得 Dim reqStrm As System.IO.Stream = ftpReq.GetRequestStream() 'アップロードするファイルを開く Dim fs As New System.IO.FileStream( _ upFile, System.IO.FileMode.Open, System.IO.FileAccess.Read) 'アップロードStreamに書き込む Dim buffer(1023) As Byte While True Dim readSize As Integer = fs.Read(buffer, 0, buffer.Length) If readSize = 0 Then Exit While End If reqStrm.Write(buffer, 0, readSize) End While fs.Close() reqStrm.Close() UpRoad = False Exit For Catch wex As System.Net.WebException Dim Err As String = wex.Status If Err = "2" Then UpRoad = True Exit For Else Int_Err = Int_Err + 1 If Int_Err = 3 Then System.IO.File.WriteAllText("C:\UL.log", wex.ToString) UpRoad = True Exit For Else Exit Try '10秒間(10000ミリ秒)停止する System.Threading.Thread.Sleep(10000) End If End If End Try Next End Function 「Streamを取得」=>「ファイルを開く」=>「Streamに書き込む」 のような手順でアップロードが行われています。 「Streamを取得」したあとに、サーバー側で接続を切断された場合reqStrm.Close() が実行されないまま、例外処理にはいります。 (つまり接続しっぱなしの状態になってしまいます) このような例外的なことが起こった場合でも、確実に切断(reqStrm.Close())されるにはどのようにソースを修正したらよろしいでしょうか? ご教授よろしくお願いします。

  • HTTPSのサイトからのダウンロード方法

    HTTPSのサイトにアクセスしてブラウザではなくテキストで表示させるにはどうすればいいのでしょうか? 通常のHTTPのサイトからは下記のコードで動作するようになりました。 これでHTTPSのサイトにアクセスしても返事が返ってきません。 今アクセスしようとしているページはまだユーザー名、パスワードが不用なページです。 ブラウザで表示させれば問題なく表示されます。 ご存知の方は教えて下さい。 [サンプルコード] Private Sub btnConnect_Click(ByVal sender As System.Object,_    ByVal e As System.EventArgs) Handles btnConnect.Click 'HttpWebRequestの作成 Dim strURL As String txtResponce.Text = "" txtResponce.Refresh() If Me.rbULR1.Checked Then strURL = txtURL1.Text Else strURL = txtURL2.Text End If Dim webreq As System.Net.HttpWebRequest = _ CType(System.Net.WebRequest.Create(strURL), _ System.Net.HttpWebRequest) 'サーバーからの応答を受信するためのHttpWebResponseを取得 Dim webres As System.Net.HttpWebResponse = _ CType(webreq.GetResponse(), System.Net.HttpWebResponse) '文字コードを指定する Dim enc As System.Text.Encoding = _ System.Text.Encoding.GetEncoding(932) '応答データを受信するためのStreamを取得 Dim st As System.IO.Stream = webres.GetResponseStream() Dim sr As New System.IO.StreamReader(st, enc) '受信して表示 Me.txtResponce.Text = sr.ReadToEnd() '閉じる sr.Close() End Sub

  • C#でHP上の特定データを自動更新で抽出したい

    ブラウザを立ち上げることなくHPに自動ログイン後、特定の表示データを抽出してリアルタイムに更新表示させたい(ブラウザでは更新ボタンのクリックが必要)。 ニコニコ動画の自動ログイン方法が公開されていますのでそれを真似て下記のプログラムを作成し、見かけ上は正常に動作していますが、これって「GetHtml」を呼ぶ度にログイン → ログアウトを繰り返すのでしょうか? もし、そうであればそれの回避方法を教えて頂けないでしょうか。(.Close()を呼ばないとか?) また、その確認方法があれば併せてお願いします。 /// ログイン (起動時1回のみ呼び出し) public bool LogIn() {  Hashtable hash = new Hashtable();  hash["username"] = "name";  hash["password"] = "123";  hash["Login"] = "login";  string s_param = "";  foreach (string s in hash.Keys)  {  s_param += string.Format("{0}={1}&", s, hash[s]);  }  HttpPost("Https", s_param); } /// POST送信 public void HttpPost(string s_url, string s_param) {  httpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(s_url);  CookieContainer cookieContainer = new CookieContainer();  httpWebRequest.CookieContainer = cookieContainer;  httpWebRequest.ContentType = "application/x-www-form-urlencoded";  byte[] data = Encoding.ASCII.GetBytes(s_param);  httpWebRequest.ContentLength = data.Length;  httpWebRequest.Method = "Post";  Stream reqStream = httpWebRequest.GetRequestStream();  reqStream.Write(data, 0, data.Length);  reqStream.Close();  WebResponse webResponse = httpWebRequest.GetResponse();  Stream resStream = webResponse.GetResponseStream();  encoder = Encoding.GetEncoding("Shift_JIS");  StreamReader streamReader = new StreamReader(resStream, encoder);  spHtml = streamReader.ReadToEnd();  streamReader.Close();  webResponse.Close(); } /// HTML受信(タイマーイベントで常時呼び出し) private string GetHtml(string s_url) {  httpWebRequest = (HttpWebRequest)WebRequest.Create(s_url);  httpWebRequest.CookieContainer = cookieContainer;  webResponse = httpWebRequest.GetResponse();  Stream resStream = webResponse.GetResponseStream();  StreamReader streamReader = new StreamReader(resStream, encoder);  string Html = streamReader.ReadToEnd();  streamReader.Close();  resStream.Close();  return Html; }

  • FTPサーバーからのファイルコピー

    勉強させてください。 vb2010.net win764bit FTPサーバーにアクセスし、FTPサーバーにあるCSVファイルをすべて 指定のフォルダにコピーしたいのです。 http://dobon.net/vb/dotnet/internet/ftpwebrequest.html#downloadfile を参考に作成しましたがうまくいきません。 1, Cドライブにコピーしたいのですが下記部分でアクセスに拒否されましたと  エラーが発生します。  Dim fs As New System.IO.FileStream( _ downFile, System.IO.FileMode.Create, System.IO.FileAccess.Write)  フォルダの設定をPrivate Const PATH_Folder = " C:\DATA"から  Private Const PATH_Folder = " \DATA"に変更するとサーバー上にアクセス(ファイルの書き込み)  が行われます。(プログラムの保存先が影響?)  指定したローカルにコピーするにはどうしららよいでしょうか。 2,1でサーバー上にファイルの書き込みができたのですが、FTPサーバーにあるCSVのデータの内容を  書くみたいでコピーできませんでした。  fs.Write(buffer, 0, readSize)をfs.CopyTo()に変更すればいいのではないかとおもい変更してみましたが、  fs.CopyTo(ここがわからない)が理解できずに動作しません。 アドバイスよろしくお願いいたします。 Imports System.Net Imports System.IO Module Module1 'FTP用host Private Const FTP_HOST = "ftp://TEST" 'FTP用USER Private Const FTP_USER = "ftpuser" 'FTP用PASSWORD Private Const FTP_PASS = "ftppass" 'FTPファイルコピー先フォルダ Private Const PATH_Folder = " C:\DATA" Private Function FTPDownLoad() As Boolean FTPDownLoad = False 'Try 'ダウンロードするファイルのURI Dim u As New Uri(FTP_HOST) 'ダウンロードしたファイルの保存先 Dim downFile As String = PATH_Folde Sub Main() '----------------------------- '-- FTP データ取得 '----------------------------- If FTPDownLoad() = False Then body = "FTPからのデータダウンロードに失敗しました。" + vbCrLf + sys_date & sys_time Exit Sub End If Private Function FTPDownLoad() As Boolean FTPDownLoad = False 'Try 'ダウンロードするファイルのURI Dim u As New Uri(FTP_HOST) 'ダウンロードしたファイルの保存先 Dim downFile As String = Palet_PATH_Folder 'FtpWebRequestの作成 Dim ftpReq As System.Net.FtpWebRequest = _ CType(System.Net.WebRequest.Create(u), System.Net.FtpWebRequest) 'ログインユーザー名とパスワードを設定 ftpReq.Credentials = New System.Net.NetworkCredential(FTP_USER, FTP_PASS) 'MethodにWebRequestMethods.Ftp.DownloadFile("RETR")を設定 'ftpReq.Method = System.Net.WebRequestMethods.Ftp.DownloadFile ftpReq.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails '要求の完了後に接続を閉じる ftpReq.KeepAlive = False 'ASCIIモードで転送する ftpReq.UseBinary = False 'PASSIVEモードを無効にする ftpReq.UsePassive = False 'FtpWebResponseを取得 Dim ftpRes As System.Net.FtpWebResponse = _ CType(ftpReq.GetResponse(), System.Net.FtpWebResponse) 'ファイルをダウンロードするためのStreamを取得 Dim resStrm As System.IO.Stream = ftpRes.GetResponseStream() 'ダウンロードしたファイルを書き込むためのFileStreamを作成 Dim fs As New System.IO.FileStream( _ downFile, System.IO.FileMode.Create, System.IO.FileAccess.Write) 'ダウンロードしたデータを書き込む Dim buffer(1023) As Byte While True Dim readSize As Integer = resStrm.Read(buffer, 0, buffer.Length) If readSize = 0 Then Exit While End If fs.Write(buffer, 0, readSize) End While fs.Close() resStrm.Close() 'FTPサーバーから送信されたステータスを表示 Console.WriteLine("{0}: {1}", ftpRes.StatusCode, ftpRes.StatusDescription) '閉じる ftpRes.Close() 'Catch ex As Exception ' MsgBox(ex.Message) ' Exit Function 'End Try FTPDownLoad = True End Function END sub

  • 画像ファイルの幅と高さを取りたい。

    C Sharp、.Net 2.0の環境で開発しています。 using (System.IO.FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { imagew = System.Drawing.Image.FromStream(fs).Width; //横幅 imageh = System.Drawing.Image.FromStream(fs).Height; //高さ } ※filePathに画像のパスを入れてます。 上記で画像ファイル(すべてjpg)の縦横の高さを取得しているのですが、 ファイルが大量にあると途中でOutOfMemoryExceptionが発生してしまい 困っています。 メモリ不足にならない、何か別のやり方があればご教授いただけないでしょうか。 宜しくお願いいたします。

  • FTPにフォルダのファイル全部をアップするには?

    Visual Basic 2010 で、ローカルの指定フォルダに作ったファイルを、FTPの指定フォルダに全てアップロードする方法を探しています。 http://dobon.net/vb/dotnet/internet/ftpwebrequest.html を参考にしましたが、ここや、Googleで見付かるサンプルコードは、1:1でファイルをアップするものばかりで、フォルダにあるファイル全部をアップロードするものはなかなかありません。 そこで、上記サイトを参考に次のようなモジュールを組んでみました。 Form1 には、テキストボックスとボタン、リストボックスを配置してあります。 Private ftpCredential As System.Net.NetworkCredential ------------------------- Sub main1() Dim Dname As String = Form1.TextBox1.Text Dim Rname As String ftpCredential = New System.Net.NetworkCredential("username", "password") Form1.ListBox1.Items.Clear() ''テキストボックスのフォルダの全ファイル一覧を取得 For Each FName As String In IO.Directory.GetFiles(Dname) Rname = FName.Replace(Form1.TextBox1.Text & "\", "") UploFtpFile("ftp://ftp.hogehoge.ne.jp/www/" + Rname, FName) Form1.ListBox1.Items.Add(Rname) Next DisconnectFtp("ftp://ftp.hogehoge.ne.jp/") End Sub ------------------------- Sub UploFtpFile(ByVal rmFile As String, ByVal loFile As String) Dim ftpReq As System.Net.FtpWebRequest = _ CType(System.Net.WebRequest.Create(rmFile), System.Net.FtpWebRequest) ftpReq.Credentials = ftpCredential ftpReq.Method = System.Net.WebRequestMethods.Ftp.UploadFile Dim reqStrm As System.IO.Stream = ftpReq.GetRequestStream() 'アップロードするファイルを開く Dim fs As New System.IO.FileStream( _ loFile, System.IO.FileMode.Open, System.IO.FileAccess.Read) 'アップロードStreamに書き込む Dim buffer(1023) As Byte While True Dim readSize As Integer = fs.Read(buffer, 0, buffer.Length) If readSize = 0 Then Exit While End If reqStrm.Write(buffer, 0, readSize) End While fs.Close() reqStrm.Close() End Sub ------------------------- Sub DisconnectFtp(ByVal uri As String) Dim ftpReq As System.Net.FtpWebRequest = _ DirectCast(System.Net.WebRequest.Create(uri), System.Net.FtpWebRequest) ftpReq.Method = System.Net.WebRequestMethods.Ftp.PrintWorkingDirectory ftpReq.KeepAlive = False End Sub End Module ------------------------- テキストボックスをフォルダとして、そのフォルダ内のファイルを全て、順番にアップロードしていき、最後に切断というのが希望の動作です。 ステップオーバーしながら監視していた所では、希望通り次々とファイルをアップロードしているようです。 気になるのは、上記のサイトの下の方に、 「TPサーバーとの接続と切断を繰り返すように思われるかもしれませんが、そうではありません」とはあるものの、これで本当に接続は切れていないのか? 相手のFTPに過負荷になるのではないか? 接続の確立や、インスタンス処理に問題があるのではないか? という疑問があります。 コードとして問題がないようでしたら、本番のプロジェクトのモジュールに組み込んで、自動ファイル生成から、そのアップロードまでが完成するのですが… なにか問題になりそうなところがあったり、「連続で全ファイルアップするなら、もっと簡単な方法があるよ」と御存知の方がいらしたら、教えてください。 よろしくお願いします。