Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anropa Microsoft Graph från dina ASP.NET Core- och OWIN-program med hjälp av Microsoft. Identity.Web och Microsoft Graph SDK för åtkomst till Microsoft 365 data och tjänster.
Förstå Microsoft Graph integrering
Microsoft Graph tillhandahåller en enhetlig API-slutpunkt för åtkomst till data i Microsoft 365, Windows och Enterprise Mobility + Security. Microsoft. Identity.Web förenklar autentisering och tokenanskaffning för Microsoft Graph, medan Microsoft Graph SDK tillhandahåller ett flytande, skrivet API för att anropa Graph-slutpunkter.
Välj Microsoft. Identity.Web.GraphServiceClient
Följande fördelar gör Microsoft.Identity.Web.GraphServiceClient till det rekommenderade sättet för att anropa Microsoft Graph.
- Automatisk tokenanskaffning: Hanterar användar- och apptoken sömlöst
- Cachehantering av token: Inbyggd cachehantering för prestanda
- Fluent API: Typsäkra, IntelliSense-vänliga Graph-anrop
- Inkrementellt medgivande: Begär ytterligare omfång på begäran
- Flera autentiseringsscheman: Stöd för webbappar och webb-API:er
- Både v1.0 och Beta: Använd stabila slutpunkter och förhandsgranskningsslutpunkter tillsammans
Installera de paket som krävs
Installera Microsoft Graph SDK-integreringspaketet:
dotnet add package Microsoft.Identity.Web.GraphServiceClient
För Microsoft Graph Beta-API:er:
dotnet add package Microsoft.Identity.Web.GraphServiceClientBeta
Konfigurera ASP.NET Core
1. Konfigurera tjänster
Lägg till stöd för Microsoft Graph i ditt program:
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Add authentication (web app or web API)
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
// Add Microsoft Graph support
builder.Services.AddMicrosoftGraph();
builder.Services.AddControllersWithViews();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
2. Konfigurera appsettings.json
Konfigurera Graph-alternativ i konfigurationsfilen:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"CallbackPath": "/signin-oidc"
},
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": ["User.Read", "User.ReadBasic.All"]
}
}
}
Konfiguration med kod:
builder.Services.AddMicrosoftGraph(options =>
{
builder.Configuration.GetSection("DownstreamApis:MicrosoftGraph").Bind(options);
});
Eller konfigurera direkt i kod:
builder.Services.AddMicrosoftGraph();
builder.Services.Configure<MicrosoftGraphOptions>(options =>
{
options.BaseUrl = "https://graph.microsoft.com/v1.0";
options.Scopes = new[] { "User.Read", "Mail.Read" };
});
3. Konfigurera nationellt molnstöd
Om du vill använda Microsoft Graph i nationella moln anger du BaseUrl i konfigurationen:
{
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.us/v1.0",
"Scopes": ["User.Read"]
}
}
}
Se Microsoft Graph distributioner för slutpunkts-URL:er.
Använda GraphServiceClient
Integrera GraphServiceClient
Mata in GraphServiceClient från konstruktorn:
using Microsoft.Graph;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[Authorize]
public class ProfileController : Controller
{
private readonly GraphServiceClient _graphClient;
public ProfileController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public async Task<IActionResult> Index()
{
// Call Microsoft Graph
var user = await _graphClient.Me.GetAsync();
return View(user);
}
}
Använda delegerade behörigheter (användartoken)
Anropa Graph för den inloggade användarens räkning med delegerade behörigheter.
Hämta grundläggande användarprofil
Hämta den aktuella användarens profilinformation från Microsoft Graph.
[Authorize]
public class ProfileController : Controller
{
private readonly GraphServiceClient _graphClient;
public ProfileController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public async Task<IActionResult> Me()
{
// Get current user's profile
var user = await _graphClient.Me.GetAsync();
return View(new UserViewModel
{
DisplayName = user.DisplayName,
Mail = user.Mail,
JobTitle = user.JobTitle
});
}
}
Begära inkrementellt medgivande
Begär ytterligare omfång dynamiskt när programmet behöver dem:
[Authorize]
[AuthorizeForScopes("Mail.Read")]
public class MailController : Controller
{
private readonly GraphServiceClient _graphClient;
public MailController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
public async Task<IActionResult> Inbox()
{
try
{
// Request Mail.Read scope dynamically
var messages = await _graphClient.Me.Messages
.GetAsync(r => r.Options.WithScopes("Mail.Read"));
return View(messages);
}
catch (MicrosoftIdentityWebChallengeUserException)
{
// ASP.NET Core will redirect user to consent
// thansk to the AuthorizeForScopes attribute.
throw;
}
}
}
Använda frågealternativ
Använd Graph SDK-frågealternativ för att filtrera, välja och beställa resultat:
public async Task<IActionResult> UnreadMessages()
{
var messages = await _graphClient.Me.Messages
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Filter = "isRead eq false";
requestConfiguration.QueryParameters.Select = new[] { "subject", "from", "receivedDateTime" };
requestConfiguration.QueryParameters.Orderby = new[] { "receivedDateTime desc" };
requestConfiguration.QueryParameters.Top = 10;
// Request specific scope
requestConfiguration.Options.WithScopes("Mail.Read");
});
return View(messages);
}
Bläddra genom resultaten
Hantera sidsidiga resultat från Microsoft Graph genom att iterera genom varje sida:
public async Task<IActionResult> AllUsers()
{
var allUsers = new List<User>();
// Get first page
var users = await _graphClient.Users
.GetAsync(r => r.Options.WithScopes("User.ReadBasic.All"));
// Add first page
allUsers.AddRange(users.Value);
// Iterate through remaining pages
var pageIterator = PageIterator<User, UserCollectionResponse>
.CreatePageIterator(
_graphClient,
users,
user =>
{
allUsers.Add(user);
return true; // Continue iteration
});
await pageIterator.IterateAsync();
return View(allUsers);
}
Använda programbehörigheter (endast apptoken)
Anropa Graph med programbehörigheter när ingen användarkontext krävs.
Anropa Graph med WithAppOnly()
WithAppOnly() Använd metoden för att göra Graph-anrop med programbehörigheter.
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
private readonly GraphServiceClient _graphClient;
public AdminController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
[HttpGet("users/count")]
public async Task<ActionResult<int>> GetUserCount()
{
// Get count using app permissions
var count = await _graphClient.Users.Count
.GetAsync(r => r.Options.WithAppOnly());
return Ok(count);
}
[HttpGet("applications")]
public async Task<ActionResult> GetApplications()
{
// List applications using app permissions
var apps = await _graphClient.Applications
.GetAsync(r => r.Options.WithAppOnly());
return Ok(apps.Value);
}
}
Konfigurera appbehörigheter
Ange en apptokenbegäran i appsettings.json:
{
"DownstreamApis": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"RequestAppToken": true
}
}
}
Omfången anges automatiskt till ["https://graph.microsoft.com/.default"].
Konfigurera detaljerade alternativ för endast appar
Ange explicita autentiseringsalternativ endast för appar i kod.
public async Task<IActionResult> GetApplicationsDetailed()
{
var apps = await _graphClient.Applications
.GetAsync(r =>
{
r.Options.WithAuthenticationOptions(options =>
{
// Request app token explicitly
options.RequestAppToken = true;
// Scopes automatically become [.default]
// No need to specify: options.Scopes = new[] { "https://graph.microsoft.com/.default" };
});
});
return Ok(apps);
}
Hantera flera autentiseringsscheman
Om din app använder flera autentiseringsscheman (till exempel webbapp + API) anger du vilket schema som ska användas:
using Microsoft.AspNetCore.Authentication.JwtBearer;
[Authorize]
public class ApiDataController : ControllerBase
{
private readonly GraphServiceClient _graphClient;
public ApiDataController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
[HttpGet("profile")]
public async Task<ActionResult> GetProfile()
{
// Specify JWT Bearer scheme
var user = await _graphClient.Me
.GetAsync(r => r.Options
.WithAuthenticationScheme(JwtBearerDefaults.AuthenticationScheme));
return Ok(user);
}
}
Konfigurera detaljerade schemaalternativ
Ange autentiseringsschemat och omfången explicit i kod.
public async Task<ActionResult> GetMailWithScheme()
{
var messages = await _graphClient.Me.Messages
.GetAsync(r =>
{
r.Options.WithAuthenticationOptions(options =>
{
// Specify authentication scheme
options.AcquireTokenOptions.AuthenticationOptionsName =
JwtBearerDefaults.AuthenticationScheme;
// Specify scopes
options.Scopes = new[] { "Mail.Read" };
});
});
return Ok(messages);
}
Använda både v1.0- och Beta-slutpunkter
Registrera och anropa både Microsoft Graph v1.0 och Beta i samma program.
1. Installera båda paketen
dotnet add package Microsoft.Identity.Web.GraphServiceClient
dotnet add package Microsoft.Identity.Web.GraphServiceClientBeta
2. Registrera båda tjänsterna
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftGraph();
builder.Services.AddMicrosoftGraphBeta();
3. Använd båda klienterna
using GraphServiceClient = Microsoft.Graph.GraphServiceClient;
using GraphBetaServiceClient = Microsoft.Graph.Beta.GraphServiceClient;
public class MyController : Controller
{
private readonly GraphServiceClient _graphClient;
private readonly GraphBetaServiceClient _graphBetaClient;
public MyController(
GraphServiceClient graphClient,
GraphBetaServiceClient graphBetaClient)
{
_graphClient = graphClient;
_graphBetaClient = graphBetaClient;
}
public async Task<IActionResult> GetData()
{
// Use stable v1.0 endpoint
var user = await _graphClient.Me.GetAsync();
// Use beta endpoint for preview features
var profile = await _graphBetaClient.Me.Profile.GetAsync();
return View(new { user, profile });
}
}
Skicka batchbegäranden
Kombinera flera Graph-anrop till en enda HTTP-begäran för att förbättra prestandan:
using Microsoft.Graph.Models;
public async Task<IActionResult> GetDashboard()
{
var batchRequestContent = new BatchRequestContentCollection(_graphClient);
// Add multiple requests to batch
var userRequest = _graphClient.Me.ToGetRequestInformation();
var messagesRequest = _graphClient.Me.Messages.ToGetRequestInformation();
var eventsRequest = _graphClient.Me.Events.ToGetRequestInformation();
var userRequestId = await batchRequestContent.AddBatchRequestStepAsync(userRequest);
var messagesRequestId = await batchRequestContent.AddBatchRequestStepAsync(messagesRequest);
var eventsRequestId = await batchRequestContent.AddBatchRequestStepAsync(eventsRequest);
// Send batch request
var batchResponse = await _graphClient.Batch.PostAsync(batchRequestContent);
// Extract responses
var user = await batchResponse.GetResponseByIdAsync<User>(userRequestId);
var messages = await batchResponse.GetResponseByIdAsync<MessageCollectionResponse>(messagesRequestId);
var events = await batchResponse.GetResponseByIdAsync<EventCollectionResponse>(eventsRequestId);
return View(new DashboardViewModel
{
User = user,
Messages = messages.Value,
Events = events.Value
});
}
Använda vanliga Graph-mönster
Använd dessa mönster för att utföra frekventa Microsoft Graph åtgärder i ditt program.
Hämta användarens chef
Hämta den inloggade användarens chef från katalogen.
public async Task<IActionResult> GetManager()
{
var manager = await _graphClient.Me.Manager.GetAsync();
// Cast to User (manager is DirectoryObject)
if (manager is User managerUser)
{
return View(managerUser);
}
return NotFound("Manager not found");
}
Hämta användarens foto
Ladda ned den inloggade användarens profilfoto som en datastream.
public async Task<IActionResult> GetPhoto()
{
try
{
var photoStream = await _graphClient.Me.Photo.Content.GetAsync();
return File(photoStream, "image/jpeg");
}
catch (ServiceException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return NotFound("Photo not available");
}
}
Skicka e-postmeddelande
Skicka ett e-postmeddelande för den inloggade användarens räkning.
public async Task<IActionResult> SendEmail([FromBody] EmailRequest request)
{
var message = new Message
{
Subject = request.Subject,
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = request.Body
},
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = request.ToEmail
}
}
}
};
await _graphClient.Me.SendMail
.PostAsync(new SendMailPostRequestBody
{
Message = message,
SaveToSentItems = true
},
requestConfiguration =>
{
requestConfiguration.Options.WithScopes("Mail.Send");
});
return Ok("Email sent");
}
Skapa kalenderhändelse
Skapa en ny kalenderhändelse med deltagare för den inloggade användaren.
public async Task<IActionResult> CreateEvent([FromBody] EventRequest request)
{
var newEvent = new Event
{
Subject = request.Subject,
Start = new DateTimeTimeZone
{
DateTime = request.StartTime.ToString("yyyy-MM-ddTHH:mm:ss"),
TimeZone = "UTC"
},
End = new DateTimeTimeZone
{
DateTime = request.EndTime.ToString("yyyy-MM-ddTHH:mm:ss"),
TimeZone = "UTC"
},
Attendees = request.Attendees.Select(email => new Attendee
{
EmailAddress = new EmailAddress { Address = email },
Type = AttendeeType.Required
}).ToList()
};
var createdEvent = await _graphClient.Me.Events
.PostAsync(newEvent, r => r.Options.WithScopes("Calendars.ReadWrite"));
return Ok(createdEvent);
}
Sök användare
Sök efter användare i katalogen efter visningsnamn eller e-postadress.
public async Task<IActionResult> SearchUsers(string searchTerm)
{
var users = await _graphClient.Users
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Filter =
$"startswith(displayName,'{searchTerm}') or startswith(mail,'{searchTerm}')";
requestConfiguration.QueryParameters.Select =
new[] { "displayName", "mail", "jobTitle" };
requestConfiguration.QueryParameters.Top = 10;
requestConfiguration.Options.WithScopes("User.ReadBasic.All");
});
return Ok(users.Value);
}
Implementera OWIN-stöd
För ASP.NET-applikationer som använder OWIN, konfigurera tokenförvärvaren och registrera Microsoft Graph-tjänster.
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.OWIN;
using Owin;
public class Startup
{
public void Configuration(IAppBuilder app)
{
OwinTokenAcquirerFactory factory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();
app.AddMicrosoftIdentityWebApi(factory);
factory.Services
.AddMicrosoftGraph();
factory.Build();
}
}
2. Anropa API från kontroller
Hämta en GraphServiceClient-instans i kontrollanten och anropa Microsoft Graph.
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
using System.Web.Http;
[Authorize]
public class DataController : ApiController
{
public DataController()
{
}
public async Task<IHttpActionResult> GetMyProfile()
{
GraphServiceClient graphServiceClient = this.GetGraphServiceClient();
var me = await graphServiceClient.Me.GetAsync();
return Ok(me);
}
}
Migrera från Microsoft. Identity.Web.MicrosoftGraph 2.x
Om du migrerar från den äldre Microsoft. Identity.Web.MicrosoftGraph-paketet (SDK 4.x) granskar du följande viktiga ändringar:
1. Ta bort det gamla paketet och lägg till nytt
dotnet remove package Microsoft.Identity.Web.MicrosoftGraph
dotnet add package Microsoft.Identity.Web.GraphServiceClient
2. Uppdateringsmetodanrop
Metoden .Request() har tagits bort i SDK 5.x:
Före (SDK 4.x):
var user = await _graphClient.Me.Request().GetAsync();
var messages = await _graphClient.Me.Messages
.Request()
.WithScopes("Mail.Read")
.GetAsync();
Efter (SDK 5.x):
var user = await _graphClient.Me.GetAsync();
var messages = await _graphClient.Me.Messages
.GetAsync(r => r.Options.WithScopes("Mail.Read"));
3. Uppdatera WithScopes() placering
Before:
var users = await _graphClient.Users
.Request()
.WithScopes("User.Read.All")
.GetAsync();
After:
var users = await _graphClient.Users
.GetAsync(r => r.Options.WithScopes("User.Read.All"));
4. Uppdatera WithAppOnly() lokalisering
Before:
var apps = await _graphClient.Applications
.Request()
.WithAppOnly()
.GetAsync();
After:
var apps = await _graphClient.Applications
.GetAsync(r => r.Options.WithAppOnly());
5. Uppdatera platsen WithAuthenticationScheme()
Before:
var user = await _graphClient.Me
.Request()
.WithAuthenticationScheme(JwtBearerDefaults.AuthenticationScheme)
.GetAsync();
After:
var user = await _graphClient.Me
.GetAsync(r => r.Options
.WithAuthenticationScheme(JwtBearerDefaults.AuthenticationScheme));
Se Microsoft Graph .NET SDK v5 changelog för fullständig migreringsinformation.
Hantering av fel
Behandla ServiceException
Fånga ODataError och MicrosoftIdentityWebChallengeUserException för att hantera Graph API-fel på ett smidigt sätt.
using Microsoft.Graph.Models.ODataErrors;
public async Task<IActionResult> GetData()
{
try
{
var user = await _graphClient.Me.GetAsync();
return Ok(user);
}
catch (ODataError ex) when (ex.ResponseStatusCode == 404)
{
return NotFound("Resource not found");
}
catch (ODataError ex) when (ex.ResponseStatusCode == 403)
{
return Forbid("Insufficient permissions");
}
catch (MicrosoftIdentityWebChallengeUserException)
{
// User needs to consent
throw;
}
catch (Exception ex)
{
_logger.LogError(ex, "Graph API call failed");
return StatusCode(500, "An error occurred");
}
}
Följ metodtipsen
1. Begär minsta omfång
Begär endast de omfång som du behöver:
// Bad: Requesting too many scopes
options.Scopes = new[] { "User.Read", "Mail.ReadWrite", "Calendars.ReadWrite", "Files.ReadWrite.All" };
// Good: Request only what you need
options.Scopes = new[] { "User.Read" };
2. Använd inkrementellt medgivande
Begär endast ytterligare omfång när det behövs:
// Sign-in: Only User.Read
// Later, when accessing mail:
var messages = await _graphClient.Me.Messages
.GetAsync(r => r.Options.WithScopes("Mail.Read"));
3. Cache GraphServiceClient
GraphServiceClient är säkert att återanvända. Registrera dig som singleton eller mata in från DI.
4. Använd välj för att minska svarsstorleken
// Bad: Getting all properties
var users = await _graphClient.Users.GetAsync();
// Good: Select only needed properties
var users = await _graphClient.Users
.GetAsync(r => r.QueryParameters.Select =
new[] { "displayName", "mail", "id" });
Felsökning av vanliga problem
Lös "Otillräckliga behörigheter för att slutföra åtgärden"
Orsak: Appen har inte nödvändiga Graph-behörigheter.
Lösning:
- Lägga till nödvändiga API-behörigheter i appregistrering
- Administratörsmedgivande krävs för appbehörigheter
- Användarmedgivande krävs för delegerade behörigheter
Lös "AADSTS65001: Användaren eller administratören har inte samtyckt"
Orsak: Användaren har inte samtyckt till begärda omfång.
Lösning: Använd inkrementellt medgivande för att utlösa medgivandeflödet med .WithScopes().
Åtgärda bild-404-fel
Orsak: Användaren har inget profilfoto.
Lösning: Hantera 404 på ett smidigt sätt och ge standardavatar.
Lösa fel med batchbegäran
Orsak: Enskilda begäranden i batchen kan misslyckas oberoende av varandra.
Lösning: Kontrollera om det finns fel i varje svar i batchen:
var userResponse = await batchResponse.GetResponseByIdAsync<User>(userRequestId);
if (userResponse == null)
{
// Handle individual request failure
}
Relaterat innehåll
- Microsoft Graph dokumentation
- Migreringsguide för Graph SDK v5
- Översikt över anropande underordnade API:er
- Ringa från webbappar
- Anropa från webb-API:er
Nästa steg: Läs mer om calling Azure-SDK:er eller anpassade API:er.