Cannot load the Projects in the C# SendGrid example solution.
"The default XML namespace of the project must be the MSBuild XML namespace. If the project is authored in the MSBuild 2003 format, please add xmlns="http://schemas.microsoft.com/developer/msbuild/2003" to the
After some Googling, it appears this is due to the new .csproj format. I do not have VS 2017, and our company has no plans to upgrade at this time. I need this to work in VS 2015. Any clues on how to get this to work? I've never worked with a MVC C# project before, so answers like "Just create a new solution" aren't going to help me because I have no idea how to do that.
Unfortunately there's no way to open this in a version of visual studio prior to 2017 now. Microsoft have chosen to drop the pre-release xproj format and not back port the new msbuild format. This doesn't prevent you from working on the code though.
You're able to use VS Code and Visual Studio Community to open and work on this project.
I haven't tried VS Code for this yet but it should be as simple as installing it and opening the folder that the project is in. VS Code will detect that it's a .net core project and prompt you to install all the recommended plugins if you don't have them.
If you have access to a mac then you could try Visual Studio for Mac but I haven't tried that yet either.
I forgot to mention that there is a sample project that doesn't rely on the new MSBuild format which can be found under ExampleNet45ASPNetProject and has its own solution for this reason.
Thanks for that info. I'm not going to install another VS client on this machine, that would get very messy very quickly. How would I then debug the SendGrid main project? I am getting a very vague error, and wanted to set some breakpoints in the main project, which is a .dll in the ExampleNet45ASPNetProject.
I wanted to try to fix the issue myself rather than try to copy/paste the most vague error in the history of errors into GitHub. I'm also converting the code into VB.net.
I guess my question is, is there no way to just convert the csproj file to the old markup?
The conversion was just done 2 weeks ago and there hasn't been any major changes since then. You could try pulling the code from right before this was done which is commit#bc34d77d449e46670520270f8d8b08ddbf585bca
Wow, thanks so much for this! I can finally see a light at the end of this tunnel. However, when trying to load those projects, it gave me an error:
The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Props" was not found. Confirm that the path in the
declaration is correct, and that the file exists on disk.
I went into C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0 and there was no DotNet folder, but there was a DNX folder with a file called Microsoft.DNX.Props instead, so I updated the projects to reference that file instead, which seemed (?) to work(ish?)
Now I'm getting an error saying "netstandard1.3 is an unsupported framework"
The project format being used there is the old xproj/project.json which was only released in preview builds, the final release was the new csproj/msbuild format. You'll most likely have to find and install the old preview tooling to get that to work. I never bothered with any of that so I'm not sure what you'll need to get it to work.
I see. I've worked with Visual Studio for years, but never really got deep into the publishing, nuget, and all the behind the scenes nitty gritty. Can you please explain what you mean by preview tooling?
Thanks for the assistance @xt0rted!
@SeanKendle,
Curious, what is the "vague error" you received? Thanks!
Ok, so first of all, I translated the code into VB.net. I'm making the call using AJAX, so the error below is in the browser console.
I kept getting a vague error "One or more errors occurred.", but then I tried changing the code to use "await" and "async" in my calls to the functions. The error stack trace has changed slightly now, with even less information.
I'll post my error first, then my code:
Message: One or more errors occurred.
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n
at System.Threading.Tasks.Task'1.GetResultCore(Boolean waitCompletionNotification)\r\n
at System.Threading.Tasks.Task'1.get_Result()"
ExceptionType: "System.AggregateException"
Private ReadOnly _client As SendGridClient
Private apiKey As String = Environment.GetEnvironmentVariable("SENDGRID_API_KEY")
Private Shared ReadOnly MessageId As String = "X-Message-Id"
Public Shared sendGridApiKey As String = "OUR_ACTUAL_API_KEY" 'obviously this has been replaced here for security purposes
<WebMethod()>
Public Shared Async Function sendEmail(ByVal req As JBL.formEntryRequest) As Threading.Tasks.Task(Of ajaxResponse)
Dim resp As New ajaxResponse
resp.success = True
Dim theEmailContract As New EmailContract
theEmailContract.ToEmailAddress = "TO EMAIL"
theEmailContract.FromEmailAddress = "FROM EMAIL"
theEmailContract.Subject = "Testing SendGrid API request"
theEmailContract.Body = "This is the body." ' innerBody.ToString()
Dim theProcessResponse As EmailResponse
resp.value = Await Send(theEmailContract)
resp.statusMessage = "Email sent successfully!"
Return resp
End Function
Public Shared Async Function Send(contract As EmailContract) As Threading.Tasks.Task(Of SendGrid.Response)
Dim _client As New SendGridClient(sendGridApiKey)
Dim emailMessage =
MailHelper.CreateSingleEmail(New EmailAddress(contract.FromEmailAddress, contract.[Alias]), New EmailAddress(contract.ToEmailAddress), contract.Subject, contract.Subject, contract.Body)
If Not String.IsNullOrWhiteSpace(contract.BccEmailAddress) Then
emailMessage.AddBcc(New EmailAddress(contract.BccEmailAddress))
End If
If Not String.IsNullOrWhiteSpace(contract.CcEmailAddress) Then
emailMessage.AddBcc(New EmailAddress(contract.CcEmailAddress))
End If
Dim r As SendGrid.Response = Await _client.SendEmailAsync(emailMessage)
Return r
End Function
```
Public Class EmailContract
Get
Return m_FromEmailAddress
End Get
Set
m_FromEmailAddress = Value
End Set
End Property
Private m_FromEmailAddress As String
Public Property [Alias]() As String
Get
Return m_Alias
End Get
Set
m_Alias = Value
End Set
End Property
Private m_Alias As String
<Required>
<Display(Name:="To Email Address")>
Public Property ToEmailAddress() As String
Get
Return m_ToEmailAddress
End Get
Set
m_ToEmailAddress = Value
End Set
End Property
Private m_ToEmailAddress As String
<Display(Name:="Cc Email Address")>
Public Property CcEmailAddress() As String
Get
Return m_CcEmailAddress
End Get
Set
m_CcEmailAddress = Value
End Set
End Property
Private m_CcEmailAddress As String
<Display(Name:="Bcc Email Address")>
Public Property BccEmailAddress() As String
Get
Return m_BccEmailAddress
End Get
Set
m_BccEmailAddress = Value
End Set
End Property
Private m_BccEmailAddress As String
<Required>
<Display(Name:="Subject")>
Public Property Subject() As String
Get
Return m_Subject
End Get
Set
m_Subject = Value
End Set
End Property
Private m_Subject As String
<Required>
<Display(Name:="Body")>
Public Property Body() As String
Get
Return m_Body
End Get
Set
m_Body = Value
End Set
End Property
Private m_Body As String
End Class
Public Class EmailResponse
Public Property DateSent() As DateTime
Get
Return m_DateSent
End Get
Friend Set
m_DateSent = Value
End Set
End Property
Private m_DateSent As DateTime
Public Property UniqueMessageId() As String
Get
Return m_UniqueMessageId
End Get
Friend Set
m_UniqueMessageId = Value
End Set
End Property
Private m_UniqueMessageId As String
End Class
This is why I want a version of the actual SendGrid API that runs locally, so I can at least figure out where in the code it's throwing the exception.
Hi @SeanKendle,
Can you try replacing:
Dim r As SendGrid.Response = Await _client.SendEmailAsync(emailMessage)
with
Dim r As SendGrid.Response = Await _client.SendEmailAsync(emailMessage).ConfigureAwait(False)
Thanks!
I made that change, and I'm still getting this error:
Message: "One or more errors occurred."
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n
at System.Threading.Tasks.Task'1.GetResultCore(Boolean waitCompletionNotification)\r\n
at System.Threading.Tasks.Task'1.get_Result()
ExceptionType: System.AggregateException
Hi @SeanKendle,
I think you need to make that change here to:
resp.value = Await Send(theEmailContract)
Please add ConfigureAwait(False) to any call that utilizes Await.
Thanks!
Hmm, same error.
How is the function sendEmail being called by your app?
It's being called with AJAX. I'm beginning to think this is the problem. I've never used async functions in ASP.net.
function sendgrid() {
console.log("sendgrid()");
var theFields = [];
theFields.push({ name: $("#txtEmailFromName").attr("name"), value: $("#txtEmailFromName").val() });
theFields.push({ name: $("#txtEmailFrom").attr("name"), value: $("#txtEmailFrom").val() });
theFields.push({ name: $("#txtEmailMessage").attr("name"), value: $("#txtEmailMessage").val() });
var emailRequest = {
formId: $(".jqvForm").data("form-id"),
fields : theFields
};
$.ajax({
type: "POST",
url: "/sendgrid.aspx/sendEmail",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ req: emailRequest }),
dataType: "json",
success: function (resp) {
console.log("resp", resp);
$.statusMessage(resp.d.statusMessage);
},
error: function (resp) {
console.log("error()", resp);
$.statusMessage(resp.statusMessage, "red");
}
});
}
Hmm, I don't have experience with this scenario.
You can try replacing .ConfigureAwait(False) with .Result, so that the asynchronous operation is complete before returning.
What's strange to me is that I tried throwing an exception immediately in the WebMethod, and it never gets thrown. That error is happening immediately upon attempting to run the WebMethod using AJAX. I'm investigating this now.
I've changed the code to the following, and I get the original error again:
<WebMethod()>
Public Shared Function sendEmail(ByVal req As JBL.formEntryRequest) As ajaxResponse
Dim resp As New ajaxResponse
resp.success = True
Dim theEmailContract As New EmailContract
theEmailContract.ToEmailAddress = "[email protected]"
theEmailContract.FromEmailAddress = "[email protected]"
theEmailContract.Subject = "Testing SendGrid API request"
theEmailContract.Body = "This is the body." ' innerBody.ToString()
'Dim theProcessResponse As EmailResponse
resp.value = Send(theEmailContract).Result
resp.statusMessage = "Email sent successfully!"
Return resp
End Function
Public Shared Async Function Send(contract As EmailContract) As Threading.Tasks.Task(Of EmailResponse)
Dim _client As New SendGridClient(sendGridApiKey)
Dim emailMessage =
MailHelper.CreateSingleEmail(New EmailAddress(contract.FromEmailAddress, contract.[Alias]), New EmailAddress(contract.ToEmailAddress), contract.Subject, contract.Subject, contract.Body)
If Not String.IsNullOrWhiteSpace(contract.BccEmailAddress) Then
emailMessage.AddBcc(New EmailAddress(contract.BccEmailAddress))
End If
If Not String.IsNullOrWhiteSpace(contract.CcEmailAddress) Then
emailMessage.AddBcc(New EmailAddress(contract.CcEmailAddress))
End If
'Dim r As SendGrid.Response = Await _client.SendEmailAsync(emailMessage)
Dim r As EmailResponse = ProcessResponse(Await _client.SendEmailAsync(emailMessage).ConfigureAwait(False))
Return r
End Function
Private Shared Function ProcessResponse(theResponse As SendGrid.Response) As EmailResponse
If theResponse.StatusCode.Equals(System.Net.HttpStatusCode.Accepted) OrElse theResponse.StatusCode.Equals(System.Net.HttpStatusCode.OK) Then
Return ToMailResponse(theResponse)
End If
'TODO check for null
Dim errorResponse As String = theResponse.Body.ReadAsStringAsync().Result
Throw New EmailServiceException(theResponse.StatusCode.ToString(), errorResponse)
End Function
ERROR:
Message "One or more errors occurred.
"StackTrace"
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n
at System.Threading.Tasks.Task'1.GetResultCore(Boolean waitCompletionNotification)\r\n
at System.Threading.Tasks.Task'1.get_Result()\r\n
at sendgrid_form.sendEmail(formEntryRequest req) in C:\Projects\ListingManager\Component Development Website\sendgrid.aspx.vb:line 68
"ExceptionType"
System.AggregateException"
Wrap the code throwing the exception in a try/catch and then in the catch do throw ex.InnerException. Any exception thrown inside of a task is wrapped in an AggregateException, calling .InnerException will let you see what's really being thrown. If there's more than one you'll need to check the .InnerExceptions property which is a list of Exceptions.
That's pretty funny you said that, I just did that before reading your response and I'm getting this error:
"Could not load file or assembly 'Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)"
I am truly annoyed by Visual Studio, and all the packages, nuget, and all this extraneous crap. It's so frustrating. It's like some secret cult with a secret language that you can't know until you know it. Sorry, I needed to vent...
So now what? I have a Newtonsoft.Json.dll file in my bin folder. I have it installed with Nuget. I'm losing my mind.
You've most likely referenced json.net v10, if so this is the same issue as #441 and in my testing was fixed by adjusting the binding redirects https://github.com/sendgrid/sendgrid-csharp/issues/441#issuecomment-307545128.
In the SendGrid solution or in my project?
Your project
I don't have anything that looks like that in my web.config file.
Here's my entire web.config, it's a very simple project:
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5.2">
<assemblies>
<add assembly="System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</assemblies>
</compilation>
<httpRuntime targetFramework="4.5.2" />
</system.web>
<appSettings>
<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Add this to <assemblyBinding ... and give it another try.
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
Thanks, I'll give that a try tomorrow, I appreciate your patience and help!
Oh my flipping flip. That was it! Thanks so much, I can't believe it was something so stupid. Ugh, sometimes programming drives me insane.
I appreciate your help!!
Most helpful comment
Add this to
<assemblyBinding ...and give it another try.