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

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

ただいまの
回答率

90.50%

  • C#

    7119questions

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

  • ASP.NET

    529questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

  • MVC

    224questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

View画面のDropDownListの値の固定と先頭のブランクについて

解決済

回答 1

投稿 編集

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

nanairo_7_

score 12

ASP.NET mvc5 を用いて、掲示板を作成している初学者です。
質問に対する回答、いつもありがとうございます。

 前提・実現したいこと

DBfirstでの"ADO.NET Entity Data Model"の作成機能を用いてModelを作成し、スキャフォールディング機能を用いてViewとControllerの自動生成をしました。

その後、ASP.NET identityを用いて実装したログイン機能を基に、トピックの中のレスの作成をしているのですが、行き詰まったので質問を投稿しました。

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

次の画像はトピックの中のレスを新規に作成するためのページなのですが、以下の問題を抱えています。

(1) レスの記入者を現在ログインしているユーザー名で固定したいが、ユーザー名をすべて表示してしまう。また、世の中の目標制作物に類似するものはそもそも「記入者=ログインユーザー名」だというのが自明なので表示してないように思えるので表示しない方法もあればご教授いただけたら幸いです。

 該当のソースコード

Controller

        // GET: Responses/Create
        public ActionResult Create()
        {
            string id = User.Identity.GetUserId();
            string name = User.Identity.GetUserName();
            ViewBag.ResOwnerId = new SelectList(db.AspNetUsers, "Id", "UserName");

            ViewBag.ResId = new SelectList(db.Responses, "Id", "Title");
            ViewBag.TopicId = new SelectList(db.Topics, "Id", "Title");
            return View();
            // return Content(id + name);
        }

        // POST: Responses/Create
        // 過多ポスティング攻撃を防止するには、バインド先とする特定のプロパティを有効にしてください。
        // 詳細については、https://go.microsoft.com/fwlink/?LinkId=317598 を参照してください。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,")] Responses responses)
        {
            if (ModelState.IsValid)
            {
                db.Responses.Add(responses);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.ResOwnerId = new SelectList(db.AspNetUsers, "Id", "Email", responses.ResOwnerId);
            ViewBag.ResId = new SelectList(db.Responses, "Id", "Title", responses.ResId);
            ViewBag.TopicId = new SelectList(db.Topics, "Id", "Title", responses.TopicId);
            return View(responses);
        }

View

@model AlbatrossOnClouds.Models.Responses

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Responses</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.TopicId, "トピック名", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("TopicId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.TopicId, "", new { @class = "text-danger" })
            </div>
        </div>


        </div>



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


        <div class="form-group">
            @Html.LabelFor(model => model.ResOwnerId, "レスの記入者", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">

               @Html.DropDownList("ResOwnerId", null, htmlAttributes: new { @class = "form-control" })
               @Html.ValidationMessageFor(model => model.ResOwnerId, "", new { @class = "text-danger" })

            </div>
        </div>


        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

 試したこと

(1)
Controllerを次のように書き換えたところ、次の画像のようにViewで表示されるDropDownListの中身がChar型になってしまいます。
return contentを用いてidとnameを表示した時にはハッシュ値のパスとユーザー名が表示できたのでidとnameには問題がないのではと考えています
(idとnameにIdentityの情報を格納し、Viewbag.ResOwnerId の値をコメントアウトしている行からその次の行のように書き換えました)

        // GET: Responses/Create
        public ActionResult Create()
        {
            string id = User.Identity.GetUserId();
            string name = User.Identity.GetUserName();
            //ViewBag.ResOwnerId = new SelectList(db.AspNetUsers, "Id", "UserName");
            ViewBag.ResOwnerId = new SelectList(id);

            ViewBag.ResId = new SelectList(db.Responses, "Id", "Title");
            ViewBag.TopicId = new SelectList(db.Topics, "Id", "Title");
            return View();
        }

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

Windows7
VS2017
ASP.NET MVC5
Net Framework 4.6.1

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • SurferOnWww

    2018/07/09 20:19

    はっきり言って長すぎます。読む気力がわいてきません。何とかなりませんか? 一番聞きたいことに絞るとか・・・

    キャンセル

  • SurferOnWww

    2018/07/12 19:00

    少しは質問の仕方を改善していただけると期待していましたが、その気なしですか? であれば、自分はお役に立てそうもないのでこのスレッドからは撤退します。何か一言返事があってもいいと思うのですが。

    キャンセル

  • nanairo_7_

    2018/07/13 13:16 編集

    すみません、質問しておいて私情を記すのが大変申し訳ないのですが、大学のレポートと試験に追われてて気が参ってました。類似箇所だからまとめた方がいいかと思ったのでこうしてましたすみません。質問内容を大幅に減らして投稿し直します。

    キャンセル

回答 1

checkベストアンサー

+2

(1) レスの記入者を現在ログインしているユーザー名で固定したいが、ユーザー名をすべて表示してしまう。

Controller のソースの db というのが何だか不明ですが、結果からすると db.AspNetUsers で DB のテーブル AspNetUsers にある全てのユーザー情報を取得しているようですね。

それをアクションメソッドで、

ViewBag.ResOwnerId = new SelectList(db.AspNetUsers, "Id", "UserName");

として、View で、

@Html.DropDownList("ResOwnerId", null, htmlAttributes: new { @class = "form-control" })

としているので、DropDownList に、DB のテーブル AspNetUsers にあるすべてのユーザーの UserName 一覧が、ドロップダウン形式で表示されるのは当然の結果ですよね?

そもそも、何故 DropDownList などを使ったのですか? 「ユーザー名で固定したい」=「ログインしているユーザー名だけを表示したい」と理解していますが、であれば、DropDownList を使うという発想にならないはずです。

普通のテキストボックスを使って、現在ログインしているユーザー名を、それに表示できればいいのですよね?

であれば、string name = User.Identity.GetUserName(); の name には目的のユーザー名を取得できているそうなので、その name を、例えば ViewBag.ResOwnerName = name; というように ViewBag に渡し、それを View で DropDownList に代えて、

@Html.TextBox("username", (string)ViewBag.ResOwnerName, new { @class = "form-control" })

 
などで表示すればよさそうです。

また、世の中の目標制作物に類似するものはそもそも「記入者=ログインユーザー名」だというのが自明なので表示してないように思えるので表示しない方法もあればご教授いただけたら幸いです。

標準のテンプレートとそれに実装されている _Layout.cshtml を使えば、画面の右上にユーザー名が表示されるはずですが、それでよさそうな気がしますけど?

ただし、[Create] ボタンをクリックして DB に INSERT する際、それにユーザー名を含める必要がある場合は、[HttpPost] を付与したアクションメソッドで何らかの手段でユーザー名を取得する必要があります。(Id も必要ならそれも)

Controllerを次のように書き換えたところ、次の画像のようにViewで表示されるDropDownListの中身がChar型になってしまいます。

上記のことが理解できれば、「Char型になってしまいます」の解決策を議論する必要なないですよね?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/14 21:44

    ScaffoldingするさいにDropDownListで表示されていたので、「それならば迂闊にいじると壊しかねないし、DropDownlistの値を一つにしてしまえば実質固定では・・・!」なんて思っていました。
    また、名前をDBにInsertすることで掲示板に誰が書き込んだのかを明示する必要があったので考えていた次第です。それに対する返答もありがとうございます・・・!
    string id = User.Identity.GetUserId();
    string name = User.Identity.GetUserName();
    の2つで取得自体はできているので試してみようと思います。

    無礼を働いてしまったにも関わらず丁寧な回答をありがとうございました。

    キャンセル

  • 2018/07/15 09:41

    > ScaffoldingするさいにDropDownListで表示されていたので

    そのようになるというのは、DB の設計からマズイところがあるからではないかと思います。

    全体的な Web アプリの構成を考えるところから始まって、そのアプリのデータのストアとなる DB をどう作るか、きちんと考えてみることをお勧めします。

    いろいろ試行錯誤しながら DB を含めた全体を作って行くなら、DB First より Code First の方が良いかもしれません。

    例としては、MVC3 でちょっと古いのが何ですが、以下の記事が良いと思います。

    連載:ASP.NET MVC入門【バージョン3対応】
    http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/index/index.html

    この記事の「第2回 Entity Frameworkコード・ファーストでモデル開発」を見てください。

    その記事の Books をトピック、Reviews をレスと考えてまずそれをベースに基本的なところを実装し、それを質問者さんのやりたいことに合わせて拡張していくことを考えるのがよさそうです。

    キャンセル

  • 2018/07/23 19:04

    とても返信が遅くなりすみません。
    データベースの設計については、経験不足の面からもかなり問題があるのでは・・・と危惧しています。
    正直、モノをなんとなく考えておそらく必要なのはここであろう、だからこうであろうという感じでDBを作っていました。
    正直、その点DBとCodeどちらを優先するかの観点で悩んでたので助言ありがたいです。Codefirstでも作成してみます。

    また、教えていただいた記事についても「こういうの読みたかった!!!」って感じでしてめっちゃ歓喜しています。ありがとうございます!

    わかりました。一気に色々手をつけずに、まずは骨組み(?)となる大事な部分を教えをもとにしてみます

    キャンセル

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

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

関連した質問

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

  • C#

    7119questions

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

  • ASP.NET

    529questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

  • MVC

    224questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。