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

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

新規登録して質問してみよう
ただいま回答率
85.49%
C#

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

ASP.NET MVC Framework

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

Q&A

解決済

1回答

11593閲覧

ActiveDirectory情報の一覧表示

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

ASP.NET MVC Framework

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

0グッド

0クリップ

投稿2018/12/04 02:55

編集2018/12/05 05:45

こんにちは。
ASP.NET MVC でC#を使って社内Webシステムの構築を始めました。
以前はVB.NETでWindowsアプリケーションの開発をしていましたが、
今回、WebシステムということでASP.NET MVCとC#に挑戦してみました。
MVCの概念やC#ならではの記述などは素人です。
開発環境:VS2015、.NET 4.5.2、MVC 5.2.3.0

目的

ActiveDirectoryからワイルドカード検索をして、取得した複数のデータをViewで一覧表示する。

できたこと

ユーザーIDを直接指定して、1件だけのデータを表示。

AdController.cs

C#

1namespace Web1.Models 2{ 3 public class AdController : Controller 4 { 5 // GET: Ad 6 public ActionResult Index() 7 { 8 var directoryEntry = new DirectoryEntry(); 9 var directorySearcher = new DirectorySearcher(directoryEntry); 10 11 // ユーザーID 12 var samAccountName = "ABC123"; 13 14 // LDAP設定、検索 15 directoryEntry.Path = "LDAP://xxx"; 16 directorySearcher.Filter = String.Format("(&(objectClass=user)(samAccountName={0}))", samAccountName); 17 18 var result = directorySearcher.FindOne(); 19 var entry = result.GetDirectoryEntry(); 20 21 // メールアドレス 22 var mailAddress = (string)entry.Properties["mail"].Value; 23 24 ViewBag.Mail = mailAddress; 25 return View(); 26 } 27 } 28} 29

Ad/Index.cshtml

<tr> <td>メールアドレス</td> <td>@ViewBag.Mail</td> </tr>

やりたいこと

  • 検索条件をワイルドカード指定(samAccountName = "ABC12*")
  • directorySearcher.FindAll()で複数のデータをViewへ渡す(↓View画面のイメージ)
cnnamemaildepartment
ABC121suzukisuzuki@jp営業
ABC122satosato@jp総務
ABC123tanakatanaka@jp経理

質問

値が一つの場合は上記のようにFindOneで取得してViewBag変数で渡していましたが、複数だとどのようになるのでしょうか?
View側ではforeachで回すのだとは思うのですが、Controller側で取得した値を格納する型がわかりません。
また、このような事をしたい場合、Modelの定義は必要でしょうか?
不慣れなので具体的なコードがあると助かります。

よろしくお願いします。


追記

AdInfo.cs

C#

1namespace Web1.Models 2{ 3 public class AdInfo 4 { 5 public string Id { get; set; } 6 public string Name { get; set; } 7 public string Mail { get; set; } 8 public string Department { get; set; } 9 10 // 追加:引数を取るコンストラクタを実装 11 public AdInfo (string Id1, string Name1, string Mail1, string Department1) 12 { 13 Id = Id1; 14 Name = Name1; 15 Mail = Mail1; 16 Department = Department1; 17 } 18 } 19}

AdController.cs

C#

1using System.DirectoryServices; 2 3namespace Web1.Models 4{ 5 public class AdController : Controller 6 { 7 public ActionResult UserList() 8 { 9 var directoryEntry = new DirectoryEntry(); 10 var directorySearcher = new DirectorySearcher(directoryEntry); 11 12 // ユーザーID 13 var samAccountName = "ABC12*"; 14 15 // LDAP設定、検索 16 directoryEntry.Path = "LDAP://xxx"; 17 directorySearcher.Filter = String.Format("(&(objectClass=user)(samAccountName={0}))", samAccountName); 18 var result = directorySearcher.FindAll(); // FindOneからFindAllに変更 19 20 // ここから修正 21 List<AdInfo> model = new List<AdInfo>(); 22 23 foreach (var user in result 24 .Cast<SearchResult>() 25 .Select(x => x.GetDirectoryEntry())) 26 { 27 var id = (string)user.Properties["sAMAccountName"].Value; 28 var name = (string)user.Properties["name"].Value; 29 var mail = (string)user.Properties["mail"].Value; 30 var department = (string)user.Properties["department"].Value; 31 32 model.Add(new AdInfo(id, name, mail, department)); 33 } 34 35 return View(model); 36 } 37 } 38} 39

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/12/04 03:15

質問は AD 情報の所得方法なのか、所得した情報を ASP.NET MVC を使ってブラウザに表示することなのか、どちらですか?
退会済みユーザー

退会済みユーザー

2018/12/04 03:18

前者は自分は答えられませんが、後者なら多分分かります。後者であれば、取得する情報がどういうものか詳しく書いてください。
退会済みユーザー

退会済みユーザー

2018/12/04 04:11

後者です。コードに書いたように"mail"などのADSI属性を指定してフィルターをかけて値を取得表示したいです。一件だけの取得はできています。
guest

回答1

0

ベストアンサー

今スマホからなので、コードが書けませんが・・・

情報を格納するクラスを Model に定義してください。そのクラスを、例えば AdInfo とすると、取得した複数のユーザーの AD 情報を、Controller で List<AdInfo> というオブジェクトを作って格納します。それを Model として View に渡すのが基本になります。

【追伸】

PC からアクセスできるようになったので、コードを書いて説明しておきます。

↓View画面のイメージ

そう表示したいのであれば、cn, name, mail, department のすべてが AdInfo クラスにないとダメでは? であれば、以下のように Model に AdInfo クラスを定義して:

Model

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; namespace Mvc5App.Models { public class AdInfo { public string Cn { get; set; } public string Name { get; set; } public string Mail { get; set; } public string Department { get; set; } } }

Controller / Action Method

上記をベースに Controller / Action Method を作って(注: List<AdInfo> model は実際は AD 情報から取得するとしてサンプルでは以下のように簡略化)、

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.ComponentModel.DataAnnotations; using Mvc5App.Models; namespace Mvc5App.Controllers { public class HomeController : Controller { public ActionResult AdInfo() { List<AdInfo> model = new List<AdInfo> { new AdInfo { Cn = "ABC121", Name = "suzuki", Mail = "suzuki@jp", Department = "営業" }, new AdInfo { Cn = "ABC122", Name = "sato", Mail = "sato@jp", Department = "総務" }, new AdInfo { Cn = "ABC123", Name = "tanaka", Mail = "tanaka@jp", Department = "経理" } }; return View(model); } } }

スキャフォールディング機能を利用して、

イメージ説明

View を生成すると以下のようになって、(追伸: @model ... がキモです。スキャフォールディングで適切にパラメータを設定すれば自動生成されます)

View

@model IEnumerable<Mvc5App.Models.AdInfo> @{ ViewBag.Title = "AdInfo"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>AdInfo</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.Cn) </th> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> @Html.DisplayNameFor(model => model.Mail) </th> <th> @Html.DisplayNameFor(model => model.Department) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Cn) </td> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Mail) </td> <td> @Html.DisplayFor(modelItem => item.Department) </td> <td> @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) | @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) | @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) </td> </tr> }

それを実行すると以下のようになります。これで分かりますか?

イメージ説明

分からないということなら本を買って読んで体系的に勉強しないと、話が通じないので、ここのような掲示板でのやり取りで解決するのは難しいと思います。

投稿2018/12/04 04:34

編集2018/12/04 21:50
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/12/04 04:36

ご回答ありがとうございます。試してみます。ひとまずお礼まで。
退会済みユーザー

退会済みユーザー

2018/12/04 06:20

不明点がありましたら質問してください。PC が使えるようになったらコードを書いて説明します。
退会済みユーザー

退会済みユーザー

2018/12/04 12:42

回答欄にコードを書いて説明しておきます。
退会済みユーザー

退会済みユーザー

2018/12/05 01:11

丁寧なご回答ありがとうございます。 > そう表示したいのであれば、cn, name, mail, department のすべてが AdInfo クラスにないとダメでは? これはイメージ説明のために書いたもので実際とは異なります。わかりにくくてすみません。修正しました。 Model で AdInfo クラスを定義して、Controller でインスタンス化し、View の @model で受け取るまでの流れ、大変参考になりました。 一番知りたかったのは、サンプル Controller では簡略化されている、 AD 情報を List<AdInfo> model に入れる部分です。 「できたこと」に書いた Index を基に、検索結果が複数帰ってくる(はずの) UserList アクションメソッドを追記しました。 foreach の中で1件ごとに new するのでしょうか?
退会済みユーザー

退会済みユーザー

2018/12/05 01:49

> 一番知りたかったのは、サンプル Controller では簡略化されている、 AD 情報を List<AdInfo> model に入れる部分です。 質問に対する 2 番目のコメントで「前者(AD 情報の所得方法)は自分は答えられませんが・・・」とお伝えしたはずです。 追記したコードの user というのが何で、それからどのように cn, name, mail, department という情報を取得できるのかを書いていただければ答えられると思いますが。
退会済みユーザー

退会済みユーザー

2018/12/05 05:34

解決しました! コードを修正しました。 > 追記したコードの user というのが何で、それからどのように cn, name, mail, department という情報を取得できるのかを書いていただければ答えられると思いますが。 foreach の中の Cast や Select のくだりはAD関係のサイトを参考にしたので説明できるほど詳しくないのですが、 このようにすると directorySearcher.FindAll() で取得した値が result に入り、user.Properties で各属性を取れるようです。 解決方法 1.SurferOnWww さんのサンプルコードをほぼそのまま実行 → 動いた 2.result の内容を foreach で全件 List<AdInfo> model に入れれば動くはず 3.サンプルでは new した時点で初期データを入れているが、本番では foreach で回すため独自クラスへのデータ追加の仕方を調査 4.AdInfo クラスに引数ごとにコンストラクタを実装 5.model.Add(new AdInfo(id, name, mail, department)); ← このAddの中でnewする記述の仕方が分からなかった という具合にやったら動きました。 SurferOnWww さん、非常に助かりました。ありがとうございました。
退会済みユーザー

退会済みユーザー

2018/12/06 00:06 編集

AD 情報は (string)user.Properties["属性名"].Value で取得できるのですね。 それを、C# 3.0 で導入されたオブジェクト初期化子(私がサンプルに書いたものです)を利用して代入しながら初期化すると、コンストラクタを追加しなくても書けるようになるはずです。 詳しくは以下の記事を見てください。 オブジェクト初期化子とコレクション初期化子 (C# プログラミング ガイド) https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers さらに進めて、Linq を使ってもっと簡略化できるかもしれませんが、それはまた別の機会に・・・
退会済みユーザー

退会済みユーザー

2018/12/06 23:54

> コンストラクタを追加しなくても おそらくそうかなとは思っていましたが、見つけた参考例がこのような記述でしたので。 次回は教わった方法で試してみようと思います。 C#自体の習熟度がまだまだ素人同然なので、面倒でも一番基本的な記述方式で覚えていこうと思います。 ラムダ式、Linq など使いこなせば便利そうなのでいずれは・・・。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問