1

I'm trying to use the SendGrid extensions for Azure WebJobs. I've tried to follow the example, but, unfortunately, the WebJob app crashes with the following error:

Could not load file or assembly 'SendGridMail, Version=6.1.0.0, Culture=neutral, PublicKeyToken=2ae73662c35d80e4' or one of its dependencies. The system cannot find the file specified.

Having run into something similar once before involving NewtonSoft's Json, I tried to fix the problem by adding the following to app.config:

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
    <assemblyIdentity name="SendGridMail" publicKeyToken="2ae73662c35d80e4" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
  </dependentAssembly>
</assemblyBinding>

Unfortunately, that didn't help (same error message).

I noticed that the WebJobs SendGrid extension nuget package install an old version of SendGrid (v6.1). But I'm trying to follow the WebJob Extensions examples, and they have the following using statement:

using SendGrid.Helpers.Mail;

and, unfortunately, the SendGrid.Helpers.Mail namespace doesn't exist in v6.1 of SendGrid.

Additional Details

Based on Tom's feedback, I uninstalled the SendGrid extensions nuget package, and installed the required libraries "manually" by editing project.json. That gets me the latest stable version of each of the libraries...but the app still crashes on startup with the same error.

Here's the startup code:

public static void Main(string[] args)
{
    var config = new JobHostConfiguration()
    {
        NameResolver = new QueueNameResolver( new AzureContext() ),
    };

    if( config.IsDevelopment )
    {
            config.UseDevelopmentSettings();
    }

    config.Tracing.ConsoleLevel = TraceLevel.Info;

    // this is the line where the exception gets thrown
    config.UseSendGrid();

    JobHost host = new JobHost( config );

    host.RunAndBlock();
}

I am following the SendGrid example, modifying a method signature in Functions.cs as follows:

public static void ProcessPhoneFileMessage(
        [QueueTrigger( "%" + nameof( ContainerQueueConstants.PhoneFiles ) + "%" )] AgencyOutreachMessage msg,
        [SendGrid] out Mail message
        )
{
    StringWriter swLogger = new StringWriter();

    try
    {
        GeneratePhoneFileJob fmJob = new GeneratePhoneFileJob( swLogger, msg );

        fmJob.Execute();
    }
    catch( Exception e )
    {
        swLogger.WriteLine( $"{nameof( GeneratePhoneFileJob )} triggered an exception, message was: {e.Message}" );
    }

    message = new Mail();

    message.Subject = "Phone File Job";
    message.AddContent( new Content( "text/plain", "Completed the Phone File Job" ) );
    message.AddContent( new Content( "text/plain", swLogger.ToString() ) );

    Personalization personalization = new Personalization();
    personalization.AddTo(new Email("mark@arcabama.com", "Mark Olbert") );
    message.AddPersonalization( personalization );
}

If I don't do the call to UseSendGrid() in the app startup code I get an exception when the method definition is parses, telling me to be sure to call UseSendGrid(). But, as I noted above, UseSendGrid() blows up.

No Exception, But No Email Either

Based on Tom's example, I modified the message-processing function so it didn't use an out Mail parameter, and simply built and sent the email from within the method body:

SendGridAPIClient sg = new SendGridAPIClient( "redacted" );
Mail message = new Mail();

message.Subject = "Phone File Job";
message.AddContent( new Content( "text/plain", "Completed the Phone File Job" ) );
message.AddContent( new Content( "text/plain", swLogger.ToString() ) );

Personalization personalization = new Personalization();
personalization.AddTo(new Email("redacted", "Mark Olbert") );
message.AddPersonalization( personalization );

sg.client.mail.send.post( requestBody: message.Get() );

The console app now starts up fine, and the message processor runs fine...but no email gets sent. Or, rather, none arrives, and when I check my dashboard at SendGrid.com there's no record of any activity.

Success!

I finally got this to work. I believe the "final" problem was that I'd neglected to include a From address for the email I was creating. Once I did that, it worked like a charm.

Mark Olbert
  • 6,584
  • 9
  • 35
  • 69
  • There does appear to be a version mismatch on SendGridMail.dll assembly. I'm getting error "Can't bind SendGridAttribute to type 'SendGrid.Helpers.Mail.Mail" when parameter binding. – Mark G Nov 04 '16 at 22:17

1 Answers1

2

Please have a try to use mydemo code. I use the WebJobs.Extensions.SendGrid library,I have tested it. It works successfully in the WebJob after publishing to WebApp. The following is my test code and package.config file:

using System;
using System.Threading.Tasks;
using SendGrid.Helpers.Mail;
using SendGrid;
namespace TestWebJob
{
   class Program
   {
     static void Main(string[] args)
     {
        Console.WriteLine($"Start to run the Execute");
        Execute().Wait();
        Console.WriteLine($"Task finished");

     }
     static async Task Execute()
     {
        string apiKey = "your sendgrid API key";
        dynamic sg = new SendGridAPIClient(apiKey);
        Email from = new Email("a@testmail.com");//a test email address
        string subject = "Hello World from the SendGrid CSharp Library!";
        Email to = new Email("b@testmail.com");// another test email address
        Content content = new Content("text/plain", "Hello, Email!");
        Mail mail = new Mail(from, subject, to, content);
        dynamic response = await sg.client.mail.send.post(requestBody: mail.Get());
    }
  }
}

The packages.config file is as following:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.Azure.WebJobs" version="1.1.1" targetFramework="net452" />
  <package id="Microsoft.Azure.WebJobs.Core" version="1.1.1" targetFramework="net452" />
  <package id="Microsoft.Azure.WebJobs.Extensions" version="1.0.1" targetFramework="net452" />
  <package id="Microsoft.Azure.WebJobs.Extensions.SendGrid" version="1.0.1" targetFramework="net452" />
  <package id="Microsoft.Data.Edm" version="5.6.2" targetFramework="net452" />
  <package id="Microsoft.Data.OData" version="5.6.2" targetFramework="net452" />
  <package id="Microsoft.Data.Services.Client" version="5.6.2" targetFramework="net452" />
  <package id="Microsoft.Tpl.Dataflow" version="4.5.24" targetFramework="net452" />
  <package id="Microsoft.Web.WebJobs.Publish" version="1.0.12" targetFramework="net452" />
  <package id="Microsoft.WindowsAzure.ConfigurationManager" version="1.8.0.0" targetFramework="net452" />
  <package id="ncrontab" version="2.0.0" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
  <package id="Sendgrid" version="8.0.5" targetFramework="net452" />
  <package id="SendGrid.CSharp.HTTP.Client" version="3.0.0" targetFramework="net452" />
  <package id="SendGrid.SmtpApi" version="1.3.1" targetFramework="net452" />
  <package id="System.Spatial" version="5.6.2" targetFramework="net452" />
  <package id="WindowsAzure.Storage" version="4.3.0" targetFramework="net452" />
</packages>
Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
  • Thanx, Tom, but that still gives me the same error. The problem appears to be related to my specifying UseSendGrid() in the app startup code. I've added more details to my question. – Mark Olbert Oct 27 '16 at 14:32
  • 1
    Tom, I marked your response as the answer, for which thanx. I had to modify the approach a bit. But the key step -- using the latest SendGrid assemblies and building the email message in the body of the method, not using the out parameter approach used by the Azure Extensions examples -- was the key. For anyone interested in the details, the problem is that the latest stable version of the Azure Extensions utilize an old version of the the SendGrid assemblies. The SendGrid API has changed a >>log<< since then. Until the next version of the Extensions comes out, Tom's approach is better. – Mark Olbert Oct 27 '16 at 17:00