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

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

ただいまの
回答率

88.91%

System.InvalidCastExceptionのエラーが解決できません。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 271

takumi0610

score 42

前提・実現したいこと

学習用で簡易版のTwitterみたいなものを作ろうとしているところで、
現在、ファイルアップロード機能と、DBへの保存処理を実装中です。
表題のエラーが発生しており、色々とネットで調べたりしてるのですが、
エラーの種類が変わったりするものの、なかなか解決できず、質問させていただいております。

流れとしましては、
「新規投稿」画面(Create.vbhtml)で、
・投稿内容(Text)
・画像(ファイルアップロードにより)(Image)
・ユーザーID(今は手入力しますが、後に自動取得させる予定)(UserId)
をフォーム入力後、
「ツイートする」ボタン押下で、DBに保存し、投稿一覧画面にリダイレクトさせる想定です。

※提供情報に不足があれば、ご指摘いただけると助かります。

発生している問題・エラーメッセージ

コントローラーファイルの
「ph.Image = text  ' データ本体」の行に、
「System.InvalidCastException」
のエラーが発生しております。
エラー文の中に文字化けのようなものも含まれておりますので、 添付画像で詳細をご確認お願いいたします。

該当のソースコード

※Viewファイル(Create.vbhtml)
※コードの途中にfontawesomeのアイコンが入っておりますが、将来的にアイコンクリックでファイルアップロード機能を持たせる予定で、
今はまだ使用しておりません。

@ModelType MyTwitter.MyTwitter.Tweet
@Code
    ViewData("Title") = "Create"
End Code

@Styles.Render("~/Content/Tweet/create.css")

<h2>新規投稿</h2>

@Using (Html.BeginForm("Create", "Tweets", FormMethod.Post, New With {.enctype = "multipart/form-data"}))
    @Html.AntiForgeryToken()

    @<div class="form-horizontal">
    <hr />
    @Html.ValidationSummary(True, "", New With {.class = "text-danger"})
    <div class="form-group">
        @Html.LabelFor(Function(model) model.Text, htmlAttributes:=New With {.class = "control-label col-md-2"})
        <div class="col-md-10">
            @Html.EditorFor(Function(model) model.Text, New With {.htmlAttributes = New With {.class = "form-control", .maxlength = "70", .rows = "4", .placeholder = "いまどうしてる?"}})
            @Html.ValidationMessageFor(Function(model) model.Text, "", New With {.class = "text-danger"})
            <div class="select-picture">
                <i class="far fa-images"></i>
                @Html.HiddenFor(Function(model) model.Image, New With {.htmlAttributes = New With {.class = "form-control"}})
            </div>
        </div>
    </div>

    <div Class="form-group">
        @Html.LabelFor(Function(model) model.UserId, htmlAttributes:=New With {.class = "control-label col-md-2"})
        <div class="col-md-10">
            @Html.EditorFor(Function(model) model.UserId, New With {.htmlAttributes = New With {.class = "form-control"}})
            @Html.ValidationMessageFor(Function(model) model.UserId, "", New With {.class = "text-danger"})
        </div>
    </div>

    <input type="file" name="fl" value="" />
    @ViewData("msg")

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="ツイートする" class="btn btn-default" />
        </div>
    </div>
</div>
End Using

<div>
    @Html.ActionLink("ホームに戻る", "Index")
</div>

※モデルファイル(Tweet.vb)

Imports System
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations

Namespace MyTwitter

    Public Class Tweet

        Public Property Id As Integer

        <DisplayName("本文")>
        <DataType(DataType.MultilineText)>
        Public Property Text As String

        Public Property Image As Byte

        Public Property CreatedAt As DateTime

        Public Property UpdatedAt As DateTime

        Public Property UserId As Integer

    End Class

End Namespace

※コンテキストクラス(MyMvcContext.vb)

Imports System.Data.Entity
Imports MyTwitter.MyTwitter

Public Class MyMvcContext : Inherits DbContext
    Public Property Tweets As DbSet(Of Tweet) ' Tweetsテーブル
End Class

※コントローラ(TweetsController.vb)

Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Entity
Imports System.Linq
Imports System.Net
Imports System.Web
Imports System.Web.Mvc
Imports System.IO
Imports MyTwitter.MyTwitter

Namespace Controllers
    Public Class TweetsController
        Inherits System.Web.Mvc.Controller

        Private db As New MyTwitterContext

        ' GET: Tweets
        Function Index() As ActionResult
            Return View(db.Tweets.ToList())
        End Function

        ' GET: Tweets/Create
        Function Create() As ActionResult
            Return View()
        End Function

        ' POST: Tweets/Create
        '過多ポスティング攻撃を防止するには、バインド先とする特定のプロパティを有効にしてください。
        '詳細については、https://go.microsoft.com/fwlink/?LinkId=317598 を参照してください。
        <HttpPost()>
        <ValidateAntiForgeryToken()>
        Function Create(<Bind(Include:="Text,Image,CreatedAt,UpdatedAt,UserId")> ByVal tweet As Tweet, ByVal fl As HttpPostedFileBase) As ActionResult

            ' コンテンツ・タイプが"image/*"であるか(画像ファイルか)
            ' をチェック
            If fl.ContentType.StartsWith("image/") Then

                ' アップロード先のパスを生成
                Dim upfile As String = Server.MapPath("~/App_Data/Photos/") & Path.GetFileName(fl.FileName)

                ' 同名のファイルが存在する場合はエラー
                If System.IO.File.Exists(upfile) Then
                    ViewData("msg") = "同名のファイルが存在します。"
                Else


                    ' EDMのコンテキスト・オブジェクトを生成
                    'Dim _db As New MyMvcEntities()
                    Dim _db As New MyMvcContext()

                    ' エンティティにアップロード・ファイルの情報をセット
                    Dim ph As New Tweet()
                    'ph.Name = Path.GetFileName(fl.FileName)  ' ファイル名
                    'ph.Mime = fl.ContentType  ' コンテンツ・タイプ

                    Dim data(fl.ContentLength) As Byte
                    fl.InputStream.Read(data, 0, fl.ContentLength)
                    'Dim text As String = data.ToString
                    Dim text As String = System.Text.Encoding.UTF8.GetString(data)
                    ph.Image = text  ' データ本体

                    ' エンティティを追加&データソースに反映
                    _db.Tweets.Add(ph)
                    _db.SaveChanges()



                    ' 画像ファイルで同名のファイルが存在しない場合は保存処理
                    'fl.SaveAs(upfile)
                    ViewData("msg") = String.Format("{0}をアップロードしました。", fl.FileName)


                End If
            Else
                ' 画像ファイルでない場合はエラー
                ViewData("msg") = "画像以外はアップロードできません。"
            End If


            If ModelState.IsValid Then
                db.Tweets.Add(New Tweet With {
            .Text = tweet.Text,
            .CreatedAt = DateTime.Now,
            .UpdatedAt = DateTime.Now,
            .UserId = tweet.UserId
            })

                db.SaveChanges()


                ' 入力元のフォームに結果を表示
                Return RedirectToAction("Index")
            Else
                Return View(tweet)
            End If

        End Function

    End Class
End Namespace

試したこと

以下の記事を参考にしました。
ファイルアップロード、およびデータベースへの保存機能につきましては、以下の2つを参考にしました。

■ファイルアップロード
https://www.atmarkit.co.jp/fdotnet/dotnettips/935aspmvcfileupload1/aspmvcfileupload1.html

■データベースへの保存
https://www.atmarkit.co.jp/fdotnet/dotnettips/939aspmvcfileupload2/aspmvcfileupload2.html

補足情報(FW/ツールのバージョンなど)

エラー内容画像
イメージ説明

統合開発環境
Visual Studio2019
(言語:VB.NET、プロジェクトテンプレート:ASP.NET Webアプリケーション MVC)

MVCフレームワークのバージョン
5.2.7

使用PC
Windows10

※平日は仕事のため、返信が19:30以降になります。
※休日の返信は不定期です。
申し訳ございませんが、どうぞよろしくお願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • takumi0610

    2020/07/05 19:50 編集

    >SurferOnWww様

    タグ付けの件、ASP.NETでも追加完了しました。

    問題としては、「ファイルアップロード後、ツイートするボタンを押下した後に保存処理がされず、エラーになってしまう」ことだったのですが、
    エラーが色々出て、その度に色々なコードをエラー解消のため変えていた結果、Imageプロパティの型と異なっている点に気づいておりませんでした。

    データ型をStringに変えることで、質問タイトルの件は解決できました。
    ありがとうございます。

    同時にまた別のエラーが発生しておりますが、質問タイトルの内容からは派生してしまいますので、
    いったん自身でエラー解決を試み、解決できなかった場合は、再度この質問に結びつける形で、質問させていただければと思います。

    自己解決ではないですが、クローズしたいのですが、この場合どのように対応させていただいたらよろしいでしょうか。

    キャンセル

  • SurferOnWww

    2020/07/05 20:16

    > クローズしたいのですが、この場合どのように対応させていただいたらよろしいでしょうか。

    回答欄に解決した方法を書いて、それで解決したとしてクローズしてください。

    次回質問する機会があったら、今回のような基本のキのところに問題がないか全体的によ~く見直してから質問してください。訳が分からないまま混乱・迷走して、山ほど関係ないことを書いて、質問するようなことは次回は絶対ないようにしていただきたく。

    キャンセル

  • takumi0610

    2020/07/05 20:21

    >SurferOnWww様

    かしこまりました。
    なるべく迷走する前に、質問投稿するなりして、後手後手にまわらないように気をつけます。
    教えていただいた方法でクローズいたします。

    ありがとうございます。

    キャンセル

回答 1

check解決した方法

0

モデルファイルのImageプロパティの型がString型になっていなかったために、発生していたエラーでした。
表題の件につきましては、この方法で解決しましたので、クローズさせていただきます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/06 10:51

    質問を見ると、根本的にダメな点が多々あって期待通りにはいくはずがないところに、上手くいかないからよく分からないまま色々いじくり回して、余計に事態が悪化して手に負えなくなって、訳が分からないままのコードを丸投げして質問したというように感じます。

    そうだとすると、それは絶対に NG です。

    本質的な問題を解決できるように質問しないと、回答者と閲覧者の時間と労力を無駄にするだけでなく、質問者さんにとってもメリットはないはずです。質問のコメント欄で「同時にまた別のエラーが発生」と言っているように別の問題が次々に出て迷走するだけでは?

    参考にしている @IT の記事は、(1) ブラウザからクライアントのファイルをアップロードし(前者の記事)、(2) サーバー側ではアップロードされてきたファイル情報からファイル名とコンテンツタイプを取得し本体共に DB に保存(後者の記事)・・・ということですよね。

    今回のスレッドの課題は、@IT の記事にない追加情報も (1) の時に一緒に送信して、それを (2) でファイルと一緒に DB に保存したいということですよね?

    であれば、次回質問する際は、質問文の最初の方の目立つところにそのように書いてください。そして、@IT の記事の通りになら問題なくできているのかも書いてください。話はそこからスタートすべきです。

    そして、手に負えない問題があるのなら、@IT の記事に戻って、そこからあなたが「@IT の記事にはない追加情報も (1) の時に一緒に送信」するのにどうすればよいと考えたのかを説明するようにしてください。いろいろいじくり回して訳が分からなくなったコードを投げるのではなく。

    キャンセル

  • 2020/07/06 20:43

    >SurferOnWww様

    >上手くいかないからよく分からないまま色々いじくり回して、余計に事態が悪化して手に負えなくなって、訳が分からないままのコードを丸投げして質問したというように感じます。
    →確かに、エラーが発生するので、エラーメッセージを調べて、その解決法でエラーが消えれば良しとして次に進んでいますが、よくわかっていません。何がわかればわかるようになるのかもわからないことが多いです。
    エラーを消してもエラーが続くときは、進んでいるのか事態が悪化しているのかもわかっておらず、ついにエラーが解決できなくなったら質問するという流れです。

    おっしゃるように、ファイルアップロードの記事はいくつかネットでも見受けられましたが、それらをDBに保存する方法、その際のモデルファイルのプロパティの定義の型、他の追加情報と一緒に送信する方法がわからず、ファイルアップロード実装のためのコードをどう活用すれば良いのか、わからないまま色々試してみたという状態です。

    一度、ファイルアップロードのみの機能実装も別のプロジェクトを作って試してみます。
    ありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る