반응형

지난 글에 이어서 이번에는 Graph API mail.read 권한을 이용하여 메일 폴더, 제목, 본문을 IIS 게시해 보겠습니다.

 

이전 글에서 작성한 프로젝트를 그대로 이어서 사용합니다.

이전 포스팅

2024.02.25 - [Microsoft 365/Graph & IIS] - Microsoft Graph & IIS. (3) Microsoft Identity Platform을 활용하여 Sample 로그인 페이지 생성

 

 

https://youtu.be/dCQmmUQiFGQ(한국어 버전)

 

https://youtu.be/tOCCgRloYOo(English Version)

 

Step1: Mail.read 권한 테스트

특정 페이지에 사용자의 메일 제목만 불러오는 방식으로 mail.read 권한 테스트를 진행하겠습니다.

기존 Appsettings.json에서

 

 Mail.Read 권한 추가 -> 저장

 

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "M365x31504705.onmicrosoft.com",
    "TenantId": "a0c898ca-2445-4e74-ab4b-afd7916549a6",
    "ClientId": "726cf3c0-8faa-4b91-a3dc-4ec4723a411b",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "MicrosoftGraph": {
    "BaseUrl": "https://graph.microsoft.com/v1.0",
    "Scopes": "user.read mail.read" //Add Mail.read
  }
}

 

HomeController.cs 수정

 

아래와 같이 기존 코드에서 //Email Titles 부분을 추가합니다.

 

using Identity.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using Microsoft.Graph;
using Microsoft.Identity.Web;

namespace Identity.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        private readonly GraphServiceClient _graphServiceClient;
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger, GraphServiceClient graphServiceClient)
        {
            _logger = logger;
            _graphServiceClient = graphServiceClient;
        }

        [AuthorizeForScopes(ScopeKeySection = "MicrosoftGraph:Scopes")]
        public async Task<IActionResult> Index()
        {
            var user = await _graphServiceClient.Me.Request().GetAsync();
            ViewData["GraphApiResult"] = user.DisplayName;
            return View();
        }

        // Email Titles
        [AuthorizeForScopes(ScopeKeySection = "MicrosoftGraph:Scopes")]
        public async Task<IActionResult> EmailTitles()
        {
            var messages = await _graphServiceClient.Me.Messages
                .Request()
                .Select(m => new { m.Subject })
                .GetAsync();

            var titles = messages.Select(m => m.Subject).ToList();
            return View(titles);
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [AllowAnonymous]
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

 

View생성

Views -> Home -> Add -> View

 

Razor View -> Empty -> Add

 

EmailTitles.cshtml -> Add

 

아래와 같이 생성됩니다.

 

아래의 내용으로 변경합니다.

@model List<string>

<h2>Email Titles</h2>
<ul>
@foreach (var title in Model)
{
    <li>@title</li>
}
</ul>

 

수정 결과

 

Start Debugging -> 로그인 -> 권한 확인 Accept

 

Home/emailtitles URL 이동하면 아래와 같이 표시됩니다.

 

OWA 비교하면 제목만 불러왔다는 것을 있습니다.

 

Step2 부터는  폴더 -> 제목 -> 본문 형태로 연결되는 페이지를 만들어 보겠습니다.

 

Step2: Action Method

Action Method는 컨트롤러 내에서 HTTP 요청을 처리하고, Microsoft Graph API를 호출하여 데이터를 가져오는 역할을 합니다. MailFolders, EmailTitles, EmailDetails와 같은 Action Method를 구현하여 각각 메일 폴더 목록, 특정 폴더의 메일 목록, 메일의 상세 내용을 가져올 것입니다.

 

HomeController.cs 수정

 

기존 Email titles 코드는 삭제합니다.

 

메일 폴더, 타이틀, 세부내용의 코드를 각각 삽입합니다.

 

//MailFolders
public async Task<IActionResult> MailFolders()
{
    var mailFolders = await _graphServiceClient.Me.MailFolders
        .Request()
        .GetAsync();

    return View(mailFolders.CurrentPage.Select(f => new MailFolderViewModel { Id = f.Id, DisplayName = f.DisplayName }).ToList());
}

//EmailTitles
public async Task<IActionResult> EmailTitles(string folderId)
{
    var messages = await _graphServiceClient.Me.MailFolders[folderId].Messages
        .Request()
        .Select(m => new { m.Subject, m.Id })
        .GetAsync();

    var titles = messages.CurrentPage.Select(m => new EmailViewModel { Id = m.Id, Subject = m.Subject }).ToList();
    return View(titles);
}

//EmailDetails
public async Task<IActionResult> EmailDetails(string messageId)
{
    var message = await _graphServiceClient.Me.Messages[messageId]
        .Request()
        .Select(m => new { m.Subject, m.Body })
        .GetAsync();

    var model = new EmailDetailsViewModel
    {
        Subject = message.Subject,
        BodyContent = message.Body.Content
    };

    return View(model);
}

 

Step3: View model

View modelView에 데이터를 전달하기 위한 모델로, Action Method에서 가져온 데이터를 정의하는 데 사용됩니다. 예를 들어, EmailViewModel은 메일의 ID와 제목을 포함합니다. 이를 통해 뷰에서 필요한 데이터를 구조화하여 관리할 수 있습니다.

 

Models 폴더 우클릭 -> Add -> Class

 

MailFolderViewModel.cs로 이름 지 -> Add

 

아래와 같이 생성됩니다.

 

아래와 같이 수정합니다.

namespace Identity.Models
{
    public class MailFolderViewModel
    {
        public string Id { get; set; }
        public string DisplayName { get; set; }
    }
}

 

#참고로namespace Identity.Models 에서 Identity 프로젝트의 네임스페이스입니다. 즉 다른이름으로 생성하였다면.. 변경하셔야합니다.

 

동일하게 Models -> Add -> Class

 

EmailViewModel.cs -> Add

 

아래와 같이 수정 -> 저장

namespace Identity.Models
{
    public class EmailViewModel
    {
        public string Id { get; set; }
        public string Subject { get; set; }
    }
}

 

같은 방식으로 EmailDetailsViewModel.cs 추가

 

아래와 같이 수정 -> 저장

public class EmailDetailsViewModel
{
    public string Subject { get; set; }
    public string BodyContent { get; set; }
}

 

Step4: View

마지막으로, View는 사용자 인터페이스를 구성하고, View Model로부터 전달받은 데이터를 표시하는 역할을 합니다. 각 액션에 대응하는 뷰 파일을 Views/Home 디렉토리에 생성합니다.

 

Views/Home 폴더 -> Add -> New Item

 

MailFolders.cshtml -> Add

 

아래와 같이 수정 저장

@model IEnumerable<Identity.Models.MailFolderViewModel>

<h2>Mail Folders</h2>
<ul>
    @foreach (var folder in Model)
    {
        <li><a href="@Url.Action("EmailTitles", "Home", new { folderId = folder.Id })">@folder.DisplayName</a></li>
    }
</ul>

 

이전에 생성한 Emailtitles.cshtml 수정.

 

다음과 같이 수정 저장

@model IEnumerable<Identity.Models.EmailViewModel>

<h2>Emails</h2>
<ul>
    @foreach (var email in Model)
    {
        <li><a href="@Url.Action("EmailDetails", "Home", new { messageId = email.Id })">@email.Subject</a></li>
    }
</ul>

 

위에서 생성한것과 동일하게 EmailDetails 생성

EmailDetails.cshtml -> Add

 

아래와 같이 수정

@model IEnumerable<Identity.Models.MailFolderViewModel>

<h2>Mail Folders</h2>
<ul>
    @foreach (var folder in Model)
    {
        <li><a href="@Url.Action("EmailTitles", "Home", new { folderId = folder.Id })">@folder.DisplayName</a></li>
    }
</ul>

 

올바르게 동작하는지 확인합니다.

Start Debugging

 

/home/mailfolders 경로로 접속

 

폴더 목록이 표시됩니다. Inbox 클릭

 

폴더 목록이 표시됩니다. Inbox 클릭

 

현재 Inbox 있는 Email목록을 확인할 있습니다. 메일 제목을 클릭합니다.

 

메일 본문이 표시됩니다.

 

이전 포스팅과 동일하게 Publish IIS 게시 과정을 진행합니다.

아래와 같이 동작을 확인합니다.

 

이렇게 Action Method, View Model, View 생성을 통해 사용자는 메일 폴더 목록을 볼 수 있고, 특정 폴더를 선택하여 그 안의 메일 목록을 확인하며, 각 메일을 클릭하여 자세한 내용을 볼 수 있게 됩니다. 

모든 코드는 ChatGPT가 생성해 주었습니다. 

반응형

+ Recent posts