質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

410閲覧

Microsoft Graph APIを使用してOneDriveにshift-jisのファイルをアップロードすると文字コードがUTF-8に変わってしまう

yuuki4673

総合スコア5

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

アップロード

アップロードは特定のファイルをウェブサーバに送るプロセスのことを指します。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2024/03/13 08:03

編集2024/03/13 08:04

分からないこと

Microsoft Graph APIを使用してOneDriveにshift-jisのファイルを文字コードを変えずにアップロードしたいのですが、アップロード後のファイルを開くとutf-8に変わってしまっています。
アップロードセッション作成時や、アップロード時に追加で必要な設定があるか、
またはPOSTやPUTリクエスト発行時に必要な設定があるか、
などご存じの方いらっしゃいましたら教えていただきたいです。

発生している問題

文字コードがutf-8に代わってしまう。
csv形式なので、エクセルで開くと文字化けしてしまう。

該当のソースコード

C#

1// **** アクセストークンは事前に取得しています **** 2 3// **** アップロードセッションを作成して、アップロード用URLを取得 **** 4 5var url = $"https://graph.microsoft.com/v1.0/drives/{driveId}/items/{itemId}:/{targetFile}:/createUploadSession"; 6var requestPost = new HttpRequestMessage(HttpMethod.Post, url); 7requestPost.Headers.Add("Authorization", $"bearer {accessToken}"); 8var parametersPost = $@"{{""@microsoft.graph.conflictBehavior"":""replace""}}"; 9requestPost.Content = new StringContent(parametersPost, Encoding.UTF8, @"application/json"); 10 11var response = m_client.SendAsync(requestPost).Result; 12var result = response.Content.ReadAsStringAsync().Result; 13var uploadSession = JsonConvert.DeserializeObject<Response>(result); 14 15 16// **** 取得したアップロード用URLでファイルをアップロード **** 17 18var encoding = Encoding.GetEncoding("shift_jis"); // ★shif_jisを取得 19using (var sr = new StreamReader(readStream, encoding)) 20{ 21 var content = sr.ReadToEnd(); 22 var Content = new StringContent(content); 23 24 Content.Headers.Clear(); 25 Content.Headers.Add("Content-Type", "text/plain; charset=Shift_JIS"); 26 Content.Headers.Add("Content-Length", "285"); // ★実際には送信するバイト数を取得して値を設定しています 27 Content.Headers.Add("Content-Range", "bytes 0-284/285");// ★実際には送信するバイト数とトータルのバイト数を取得して値を設定しています。形式は同じです。 28 29 m_client.PutAsync(uploadSession.uploadUrl, Content).Result; // ★uploadSession.uploadUrl = 取得したアップロード用URLです。 30}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

●コンテンツヘッダーを'application/octet-stream'に変更してみましたが、解決せずUTF-8に変わってアップロードされてしまいました。

C#

1Content.Headers.Add("Content-Type", "application/octet-stream; charset=Shift_JIS");

●アップロード元ファイルはSJISとなっていることを確認済みです。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2024/03/13 09:31

よく知らないので間違っているかもしれませんが、ご質問のコードを軽く見た限りでは、シフトJISのファイル内容を読み込んでUTF-8に変換してから送信しているように思えます。 で、.NETのリファレンスを拾い読みしたことをもとにした当て推量ですが、StreamReaderではなくFileStreamを使ってファイルから読み込み、StringContentではなくByteArrayContentを使って送信する内容を作れば、期待した通りの結果になったりするのかもしれません。
yuuki4673

2024/03/14 00:22

コメントありがとうございます! 返信が遅くなり申し訳ございません。。 StreamReaderをFileStreamに、StringContentをByteArrayContentに変更するというご提案ありがとうございます!! まずはStringContentをByteArrayContentに変更して出力を試してみたところ、見事に解決いたしました! (ちなみにStreamReaderをFileStreamにの部分ですが、正確にはStreamWriterでMemoryStreamにSJISで展開しておいて、そのSJIS形式のMemoryStream値をbyte[]型にしてByteArrayContentで送信した感じにしました。) ぜひベストアンサーに選びたいのでお手数おかけしてしまうのですが、 同じ内容を回答欄に投稿いただけますでしょうか??
ikedas

2024/03/14 00:26

最終的にご自分で解決されたのですから、完成したコードなども含めどうやって解決したのかを自分で回答として投稿し、質問を解決ずみにしてください。
yuuki4673

2024/03/14 01:49

ikedasさん ありがとうございます! 別の方の回答でも解決することができ、今回はそちらを適用することとさせていただきました! ikedasさんのご提案も非常に参考になり知識が深まりました! 本当にありがとうございました!m(_ _)m
guest

回答1

0

ベストアンサー

まず、.NET の string の文字エンコーディングは UTF16 です。
読み取った文字エンコーディングが ShiftJIS だからって油断してはなりません。

なので出力でどのエンコーディングが指定されているかが重要です。

今回の出力に使っているのは StringContent ですが

new StringContent(content)
をすると渡されるのは

cs

1public StringContent(string content) 2 : this(content, DefaultStringEncoding, DefaultMediaType) 3{ 4}

https://github.com/dotnet/runtime/blob/18c3ad05c3fc127c3b7f37c49bc350bf7f8264a0/src/libraries/System.Net.Http/src/System/Net/Http/StringContent.cs#L21-L24

DefaultStringEncoding の定義は

cs

1internal static readonly Encoding DefaultStringEncoding = Encoding.UTF8;

https://github.com/dotnet/runtime/blob/18c3ad05c3fc127c3b7f37c49bc350bf7f8264a0/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs#L25

となっている為、明示的に ShiftJIS の Encoding を渡せばいいだけではないでしょうか?

投稿2024/03/14 00:05

編集2024/03/14 00:17
juner

総合スコア453

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuuki4673

2024/03/14 01:46

回答ありがとうございます!! 細かいソースや定義の情報などもご提示いただき、分かりやすく理解が深まりました! new StringContent(content) の第二引数でShiftJISを指定することで解決いたしました! new StringContent(content) にエンコーディングを指定できるのに気づけなかったです、、 非常に助かりました!m(_ _)m "Content-Length"に指定するバイト長も素直にcontentのバイト数を指定するとエラーになっていて、 何故か分からなかったのですが、new StringContentでUTF-8に変わってしまっていたのでバイト長も変わってしまっていたのですね。。 無事に解決することができ、うまくいかない原因も完全に理解できましたので、 ベストアンサーに選ばせていただきました! ありがとうございました!!
juner

2024/03/14 05:57

ヘッダー等も そちらのコードにある様に requestPost.Content = new StringContent(parametersPost, Encoding.UTF8, @"application/json"); の様に 第三引数でmime-typeまで設定できるまでありました。(というか Content-Length は StringContentが対応しているのでわざわざ設定する必要は無いのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問