You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Microsoft Graph发邮件遇System.IO.FileLoadException问题求助

生产环境下Microsoft Graph邮件模块抛出System.IO.FileLoadException的排查建议

本地VS2019环境中使用Microsoft Graph发送邮件功能运行正常,但部署到生产环境后邮件模块崩溃,抛出System.IO.FileLoadException异常。Windows日志精简信息如下:

Toepassing: CIP.WindowsClient.exe Framework-versie: v4.0.30319 Beschrijving: het proces is beëindigd als gevolg van een onverwerkte uitzondering. Uitzonderingsinformatie: System.IO.FileLoadException bij Microsoft.Identity.Client.ApplicationConfiguration..ctor() bij Microsoft.Identity.Client.ConfidentialClientApplicationBuilder.Create(System.String) bij CIP.Helper.Mail.GraphMail+<

已确认部署所有相关DLL文件、配置中的TenantId/ClientId加载正常,替换过DLL文件但问题仍未解决,需要排查建议。

相关代码

using Microsoft.Graph;
using Microsoft.Identity.Client;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Configuration;
using System.Net.Http.Headers;


namespace CIP.Helper.Mail
{
public class GraphMail
{
    private static GraphServiceClient _userClient;
    private static User _user;

    public GraphMail()
    {
        InitializeGraphForUserAuth();
    }

    private async static void InitializeGraphForUserAuth()
    {
        string auth = string.Concat("https://login.microsoftonline.com/", ConfigurationManager.AppSettings["TenantId"]);

        
            IConfidentialClientApplication application = ConfidentialClientApplicationBuilder.Create(ConfigurationManager.AppSettings["ClientId"])
                          .WithClientSecret(ConfigurationManager.AppSettings["ClientSecret"])
                          .WithAuthority(new Uri(auth))
                          .Build();


            System.Windows.MessageBox.Show(string.Format(ConfigurationManager.AppSettings["TenantId"].ToString()));                            

            try
            {
                _userClient = new GraphServiceClient("https://graph.microsoft.com/v1.0",
                    new DelegateAuthenticationProvider(async (requestMessage) =>
                    {
                        AuthenticationResult AuthToken = await application.AcquireTokenForClient(new string[] { "https://graph.microsoft.com/.default" }).ExecuteAsync();
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", AuthToken.AccessToken);
                    }
                    ));
            }
            catch (MsalUiRequiredException ex)
            {
                // The application doesn't have sufficient permissions.
                // - Did you declare enough app permissions during app creation?
                // - Did the tenant admin grant permissions to the application?
                Console.WriteLine("Exception: {0}", ex.Message);
            }
            catch (MsalServiceException ex) when (ex.Message.Contains("AADSTS70011"))
            {
                // Invalid scope. The scope has to be in the form "https://resourceurl/.default"
                // Mitigation: Change the scope to be as expected.
                Console.WriteLine("Scope provided is not supported");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException);
            }
        //}
        //catch (FileLoadException ex)
        //{
        //    System.Windows.MessageBox.Show(ex.InnerException.ToString());
        //}
        //catch(Exception ex)
        //{
        //    System.Windows.MessageBox.Show(ex.InnerException.ToString());
        //}

    }
   
}
}

app.config配置

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.net>
<defaultProxy>
  <proxy bypassonlocal="true" usesystemdefault="false" />
</defaultProxy>
</system.net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<appSettings>        
<add key="TenantId" value="<guid>"/>
<add key="ClientId" value="<guid>"/>
<add key="ClientSecret" value="<value>"/>
</appSettings>
</configuration>

排查建议

  • 检查程序集版本冲突
    使用fuslogvw.exe(程序集绑定日志查看器)捕获程序集加载失败的详细日志,确认是否存在Microsoft.Identity.Client(MSAL)或Microsoft.Graph的版本不匹配问题。同时在app.config中添加程序集绑定重定向,强制指定使用的版本:

    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
          <assemblyIdentity name="Microsoft.Identity.Client" publicKeyToken="0a613f4dd989e8ae" culture="neutral" />
          <bindingRedirect oldVersion="0.0.0.0-[当前使用版本]" newVersion="[当前使用版本]" />
        </dependentAssembly>
        <dependentAssembly>
          <assemblyIdentity name="Microsoft.Graph" publicKeyToken="31bf3856ad364e35" culture="neutral" />
          <bindingRedirect oldVersion="0.0.0.0-[当前使用版本]" newVersion="[当前使用版本]" />
        </dependentAssembly>
      </assemblyBinding>
    </runtime>
    
  • 确认.NET Framework版本一致性
    检查生产环境服务器上的.NET Framework版本是否为4.6.2,若版本低于该版本,升级至对应版本,确保与开发环境一致。

  • 验证文件权限
    确认应用程序运行账户对DLL所在目录有读取权限,避免因权限不足导致程序集无法加载。

  • 修复异步方法调用问题
    代码中InitializeGraphForUserAuth为async static void方法,会导致异常无法被上层捕获且可能引发上下文问题。改为async Task并使用异步工厂模式调用:

    public static async Task<GraphMail> CreateAsync()
    {
        var instance = new GraphMail();
        await instance.InitializeGraphForUserAuthAsync();
        return instance;
    }
    
    private async Task InitializeGraphForUserAuthAsync()
    {
        // 原方法逻辑保持不变
    }
    
  • 检查MSAL依赖项完整性
    核对MSAL的所有依赖程序集(如Microsoft.Identity.Client.Extensions.dll等)是否都已部署到生产环境,可通过NuGet包管理器查看依赖列表逐一确认。

  • 启用详细异常日志
    在生产环境中添加FileLoadException的捕获逻辑,输出完整异常信息定位问题:

    catch (FileLoadException ex)
    {
        System.Windows.MessageBox.Show($"无法加载程序集:{ex.FileName}\n错误信息:{ex.Message}\n内部异常:{ex.InnerException?.Message}");
    }
    

内容的提问来源于stack exchange,提问作者JeroenZenM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 16:45:35