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

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

ただいまの
回答率

90.48%

  • C#

    9213questions

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

  • ASP.NET MVC Framework

    106questions

    ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

  • Razor

    25questions

    RazorはASP.NET Web PagesとASP.NET MVCで使われているビュー・エンジンです。HTMLマークアップとC#またはVisual Basicのコードに対応しています。マークアップとコードの間の切り替えは"@"で記されています。

ビュー・ヘルパーFor型(TextBoxFor)使用時に、nameを指定したい

解決済

回答 1

投稿 編集

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

tkta

score 5

ビュー・ヘルパーFor型(TextBoxFor)使用時に、nameを指定したい

前提・実現したいこと
TextBoxForで、modelに紐づいた?nameではなく、@Html.TextBoxを使用する際に指定したnameを<input>タグに付けたい

環境
ASP.NETMVC5
VisualStudio2013
c#

発生している問題・エラーメッセージ 該当のソースコード

↓↓↓求めている形↓↓↓
<input class="form-control input-information" id="hoge" name="ABC" type="text" value="ほげ">

@Html.TextBoxForを用いて、上記の形で出力したい。

@Html.TextBoxFor(m => item.MEMBER.NAME, new { @class = "form-control input-information" ,name = "ABC" })
↑上記でnameをABCと明示しても、nameがABCとならず、

<input class="form-control input-information" id="item.MEMBER.NAME" name="item.MEMBER.NAME" type="text">
のような感じで出力されます。

@Html.TextBoxForではなく、
@Html.TextBox("ABC",item.MEMBER.NAME, new { @class = "form-control input-information"})とすれば、
求めている形で出力されます。

試したこと
下記サイトの内容を試してみても、自分で指定したnameがつかないです。
https://code.i-harness.com/ja/q/5c6f89

補足
nameの箇所以外、不必要そうなところは削除していますので「こういうhtmlにはならない、おかしい」と思われるかもしれませんが、そこはスルーしてください。
知りたいことは、htmlヘルパー(TextBoxFor)を使用した際にnameを指定することが可能なのか、もし可能ならその方法を知りたい、ということです。
よろしくお願いします。

画面イメージ
イメージ説明
イメージ説明

追記

 >EditorFor を利用すると、モデルのプロパティの型によってレンダリングされる html 要素が適切に選ばれる

EditorForがモデルに紐づいたフォームを作るというのは理解していたのですが、
テキストボックスならTextBoxFor、
チェックボックスならCheckBoxFor、
という風に、ソース上で明示した方がわかりやすいんじゃ?
と、思うことがあり、EditorForの優位性をあまり実感できていないというのが現状です……。

>TextBoxFor の方は、ダメだったような・・・(定かではないです) 

数字入力のみのフォームに、文字を入力した際、
モデルのErrorMessageが表示されるのは確認しました。

>idを指定しないと、「.」「[」「]」が「_」に変換されてしまうみたいで?

の件ですが、
Viewのコード↓

@Html.EditorFor(m => m.MEMBER[num].BOSS.NAME)

をchromeの開発者ツールで確認してみたところ、下記のように表記されていて、

<input class="text-box single-line" id="m_MEMBER_0___BOSS_NAME" name="m.MEMBER[0].BOSS.NAME" type="text" value="安藤">

internet explorerの開発者ツールで確認してみても、

<input class="text-box single-line" id="m_MEMBER_0___BOSS_NAME" name="m.MEMBER[0].BOSS.NAME" type="text" value="安藤" />

と同様のコードが表示されており、id属性値もエンコード???が起きてしまってます(TextBoxForでも同じ状況です)。
modelの書き方が原因な気もしてきましたが、
SurferOnWwwさんにこれ以上お手数をおかけするわけにもいかないので、
この部分は気にしないでください。

それも紹介した記事「コレクションのデータアノテーション検証」に例が出ていますが、以下のようにすれば良いはずですけど・・・
私のレスをきちんと読んでもらっているでしょうか? 読んだけど意味不明だったということでしょうか?

いや読んではいるのですが、

@Html.ValidationMessageFor(m => m.CountryList[i].Name)


に、クラス属性を与えたく、

@Html.ValidationMessageFor(m => m.CountryList[i].Name,new{@class="text-danger"})


と、するとエラーが出てしまい、
クラスの付与の仕方がわからず、困り果てコメントのコードに達しました。

最終的には、

@Html.ValidationMessageFor(m => m.CountryList[i].Name,"",new{@class="text-danger"})


との形にすれば、class属性を付与できると発見しました。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • SurferOnWww

    2019/01/22 07:40 編集

    タブという言葉に目が行って理解不能になってしまいましたが、要するにモデルに定義してあるクラスのオブジェクトのコレクションがアクションメソッドの引数にモデルバインドできれば良いのですか?

    キャンセル

  • tkta

    2019/01/22 11:51

    「,Name = "ABC"」の形でnameを指定できました。
    余談ですが、「,@Name = "ABC"」でも指定可能
    「,name = "ABC"」「,@name = "ABC"」は、指定不可でした。
    仕組みがわからすぎて怖いですが、こういう方法もあるのですね。
    勉強になります!!

    SurferOnWwwさん、その通りです!!
    ループ処理にTextBoxForを使用し、複数入力フォームを作成しているのですが、それらの<input>タグのnameが同じのため、意図的に連番をつけて対応するのか?、と、考えた結果です。
    説明が下手で大変申し訳ございません。

    キャンセル

  • SurferOnWww

    2019/01/22 12:31

    「モデルに定義してあるクラスのオブジェクトのコレクションがアクションメソッドの引数にモデルバインドできれば良い」ということであれば、Microsoft 公式解説書にも書かれているやり方があります。詳しくは後で回答欄に書いておきます。(Name を使うなどというものではありません)

    キャンセル

回答 1

checkベストアンサー

+3

要するに、モデルに定義してあるクラスのオブジェクトのコレクションがアクションメソッドの引数にモデルバインドできれば良いということだそうですので、そうするにはどうすればよいかについて回答します。

コレクションのモデルバインディングですが、それがうまく行われるようにするには、レンダリングされる html 要素の name 属性が連番のインデックスを含むようにします。

具体的には、name="prefix[index].Property" というパターンにします。prefix の部分にはアクションメソッドのパラメータ(仮引数)名が入ります。index は 0 から始まる連番です。

なので、質問者さんが質問のコメントに書かれた、

@Html.TextBoxForを使用する際、nameでMEMBER[0].TITLEみたいな形を明示できないかなあと試行錯誤しています

・・・というような形にするというのは正解です。

では、TextBoxFor や EditorFor(EditorFor を使うのがお勧めです)でどのように name 属性を設定するかですが、以下の記事が参考になると思いますので目を通してください。

コレクションのデータアノテーション検証
http://surferonwww.info/BlogEngine/post/2014/09/01/validation-of-collection-data-during-model-binding-using-data-annotation.aspx

他のコード例としては以下の Teratail の記事に私の回答がありますので見てください。

ASP.NET MVC ラジオボタンのView/Controllerのやり取り
https://teratail.com/questions/151505

不明点があれば質問してください。

【追記】

下の 2019/01/23 18:09 の私のコメントで「長くなりそうなので回答欄に追記します」と書きましたが、それを以下に書きます。

EditorFor、TextBoxForの違いがわからなく

EditorFor を利用すると、モデルのプロパティの型によってレンダリングされる html 要素が適切に選ばれる(例: bool 型にするとチェックボックスになる)こと、プロパティ付与される DataType 属性によって、生成される html ソースの input 要素の type 属性が変わってくる(例:MultilineText の場合は input 要素でなく、textarea 要素になる)ことがあります。

あと、紹介した前者の記事にも書きましたが、ASP.NET がレンダリングする html 要素に、クライアントサイドでの jQuery ライブラリによる検証に必要な属性(例: data-val="true" など)が追加されないと、クライアント側での検証ができません。EditorFor を使用すると、クライアント側での検証に必要な属性が自動的に付与されます。

TextBoxFor の方は、ダメだったような・・・(定かではないです) 

EditorForですと、「text-box」「single-line」クラスが自動で付与されていたので、

class="text-box single-line" はデフォルトでハードコーディングされている属性だそうです。MVC 5.1 からは EditorFor にも任意の属性が付与できるようになりました。詳しくは以下の記事を見てください。

EditorFor での属性の付与方法
http://surferonwww.info/BlogEngine/post/2018/02/23/how-to-pass-html-attributes-in-editorfor.aspx

idを指定しないと、「.」「[」「]」が「_」に変換されてしまうみたいで?

それはどういうことなのか分かりませんが、上に紹介した記事に書いたように、

@Html.EditorFor(m => m.LastName,
  new { htmlAttributes =
    new { @class = "coolTextBox", data_date = "12-02-2012" } })


とすれば、レンダリングされる html は以下のようになるのですが・・・

<input 
  class="coolTextBox text-box single-line" 
  data-date="12-02-2012" 
  id="LastName" 
  name="LastName" 
  type="text" 
  value="Gee" />

余談ですが、List型のValidationの結び付け方がわからなく、

それも紹介した記事「コレクションのデータアノテーション検証」に例が出ていますが、以下のようにすれば良いはずですけど・・・

@Html.LabelFor(m => m.CountryList[i].Name)
@Html.EditorFor(m => m.CountryList[i].Name)
@Html.ValidationMessageFor(m => m.CountryList[i].Name)

私のレスをきちんと読んでもらっているでしょうか? 読んだけど意味不明だったということでしょうか?

【追記2】

下の 2019/01/24 11:04 の私のコメントで「レス不要かもしれませんが、気になった点がありますので、後で回答欄に追記しておきます」と書きましたが、それを以下に書きます。

質問者さんが回答欄に追記された件に対するレスです。

数字入力のみのフォームに、文字を入力した際、モデルのErrorMessageが表示されるのは確認しました。

私の回答欄に【追記】で書いた「TextBoxFor の方は、ダメだったような・・・」は思い違いでした。間違った情報ですみません。

EditorFor に代えて TextBoxFor を使っても、クライアント側の検証用に使う属性 data-val-* は付与され、クライアント側での jQuery / JavaScript による検証はかかることを確認しました。

下の画像で、網掛けした方の input 要素が TextBoxFor 、その下の input 要素が EditorFor でレンダリングされたものです。

イメージ説明

ただし、Model のクラスのプロパティに付与した DisplayFormatAttribute が TextBoxFor では無視されます。

属性は以下の画像の赤枠のように付与していますが、上の画像の赤枠で示した value 属性の通り、TextBoxFor でレンダリングすると無視されるようです。他にも期待通りの結果にならないことがあるかもしれず、要注意だと思います。

イメージ説明

idを指定しないと、「.」「[」「]」が「_」に変換されてしまうみたいで?

html コードを貼っていただいて意味が分かりました。そこは、上の画像でしめした通り、自分の環境でも同じです。

裏技的な手段でコントロールする方法があるかもしれませんが、やり方は知りませんし、その必要もないと思っています。

id が勝手に書き換わると困るケースは、クライアントスクリプトで getElementById とかを使いたい場合がありますが、MVC4 以降には Html ヘルパーに IdFor メソッドが用意されていて、それを使えば html にレンダリングされた時の id の値は取得可能です。

詳しくは以下の記事を見てください。

Control.ClientID と Html.IdFor
http://surferonwww.info/BlogEngine/post/2017/02/19/control-clientid-and-html-idfor.aspx

name 属性の値を取得したいというケースもあるかもしれませんが、そのための Html ヘルパー NameFor も用意されています。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/22 14:45 編集

    ご丁寧な回答をいただき、ありがとうございます。
    急ぎの用件が入ったため、数日後になるかもしれませんが、必ずやろうと思います。
    不明点等があった場合、質問させていただきますので、
    お手数をおかけしますがご回答いただければ、と思います。
    取り急ぎのご連絡で失礼します。

    キャンセル

  • 2019/01/23 15:36

    SurferOnWwwさんの回答にある
    上記の方法を参考にして無事に実装できました。

    EditorFor、TextBoxForの違いがわからなく、
    EditorForですと、「text-box」「single-line」クラスが自動で付与されていたので、
    今回はTextBoxForで下記のように実装しました。

    @Html.TextBoxFor(m => m.MEMBER[num].BOSS.NAME, new { @class = ~~~ })

    idを指定しないと、
    「.」「[」「]」が「_」に変換されてしまうみたいで?、
    <input id = "m_MEMBER_num__BOSS_NAME">みたいな気持ち悪いタグが生まれてきたので、
    ひとつづつ属性名を指定して上書きしました。

    余談ですが、List型のValidationの結び付け方がわからなく、
    そのうえ、@Html.ValidationMessageForだと、
    「,.new{@class = ~}」を記載すると、引数が云々?の警告を受けたので、
    @Html.ValidationMessage("MEMBER[" + num + "].BOSS.NAME", new { @class = "text-danger" })
    と強引な方法でvalidationを付与してみました。

    多分解決しました。

    SurferOnWwwさん、ありがとうございました。
    また、wwbQzhMkhhgEmhUもありがとうございました。

    色々と勉強になりました!!

    キャンセル

  • 2019/01/23 18:09

    上のコメントにレスしようとしましたが、長くなりそうなので回答欄に追記します。

    キャンセル

  • 2019/01/24 10:14

    質問の追記欄に追加しました。

    キャンセル

  • 2019/01/24 11:04

    返答いただきありがとうございました。
    レス不要かもしれませんが、気になった点がありますので、後で回答欄に追記しておきます。

    キャンセル

  • 2019/01/24 13:39 編集

    確認までしていただき、ありがとうございます。

    TextBoxForとEditorForの細かい仕様を理解できました。
    DisplayFormatの挙動が違うのですね。

    今までDisplayNameや、RegularExpression等の入力検証系のしか設定してなく、
    あまりDisplayFormatは使用してこなかったのですが、これからは意識してみます。
    調べてみたら、DisplayFormatを設定しつつ、
    適応されないTextBoxForを意図的に使用する方法もあるようで奥が深いですね。
    https://redwarrior.hateblo.jp/entry/2016/08/22/090000


    >html コードを貼っていただいて...
    こういう仕様なのですね。バグ的なものかと思ってました...。
    参考サイトのような方法で、対応できるのも理解できました。
    目から鱗です。

    ご丁寧に説明していただき、ありがとうございました。
    色々と説明が足りず、申し訳ございませんでした。
    また何かございましたら、よろしくお願いします。

    キャンセル

  • 2019/01/25 10:49

    今さらながらですが、TextBoxFor ではサーバー側の検証に問題があったケースを思い出しましたので、連絡しておきます。

    詳しい話は以下の記事を見てください。

    Modelの型の検証を無効化・またはエラーメッセージを日本語にしたい
    https://teratail.com/questions/146213

    要約すると・・・

    public int Price { get; set; } というような int 型のプロパティをベースに、TextBoxFor で html をレンダリングすると、

    <input
    type="text"
    data-val-number="The field Price must be a number." ... />

    となって、数字以外を入力すると、クライアント側での検証で、出てほしくないのに "The field Price must be a number." というエラーメッセージが出る。

    EdotorFor で html をレンダリングすると、

    <input
    type="number"
    data-val-number="The field Price must be a number." ... />

    結果、ブラウザ依存ですが、例えば IE11 の場合、数字以外の文字を入力し、フォーカスを外すとクリアされ(テキストボックスは空白になる)、エラーメッセージは出ない。Chrome では数字以外入力できないという結果になります。

    いずれにしても出てほしくない "The field Price must be a number." というエラーメッセージは出なくなります。

    キャンセル

  • 2019/01/25 14:06 編集

    細かい話ですこし理解が追い付いていない可能性もありますが、
    EditorForだと、モデルの型に適したフォームを作成する
    TextBoxForだと、常にテキストボックスを作成する
    という点を、複数のプラウザで確認できました。

    Datetime型で試した際、
    EditorForだとvalueの値が「2019/01/17」
    TextBoxForだとvalueの値が「2019/01/17 0:00:00」という部分の違いも発見できました。

    二時間ぐらいプラウザを変えたりして色々試したんですが、
    混乱してきたので試すのはこれ以上やめておきます。
    まあ難しいです。

    一応、日付データはSqlServerから持ってきていて、
    メタデータクラスを設定してたりするので、人によって結果が違うかもしれません。

    わざわざご連絡いただき、ありがとうございました。

    キャンセル

  • 2019/01/25 15:02

    要するに、EditorFor を利用することを前提に、上に書いた様に付与した属性が上手く働くような配慮がいろいろとされているようですので、TextBoxFor ではなくて EditorFor を使うのがお勧めということです。

    キャンセル

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

  • C#

    9213questions

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

  • ASP.NET MVC Framework

    106questions

    ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

  • Razor

    25questions

    RazorはASP.NET Web PagesとASP.NET MVCで使われているビュー・エンジンです。HTMLマークアップとC#またはVisual Basicのコードに対応しています。マークアップとコードの間の切り替えは"@"で記されています。