Weird Json conversion error using lambda - c#

I have a Json document being sent to a Web API that is converted to an array of Addresses. If I send one address the following code works, but if I send two it dies a nasty death. Any ideas?
Input to web service that is failing looks like this:
[
"\"TrackingIdTest_2\"",
"[
{\"CustomerAddressKey\":\"1\",\"Address\":\"6069 W STUDIO CT\",\"City\":\"LOS ANGELES\",\"State\":\"CA\",\"Zipcode\":\"\"}
,{\"CustomerAddressKey\":\"2\",\"Address\":\"1095 6th Ave\",\"City\":\"NEW YORK\",\"State\":\"NY\",\"Zipcode\":\"\"}
]"
]
If I send this it works:
[
"\"TrackingIdTest_2\"",
"[
{\"CustomerAddressKey\":\"1\",\"Address\":\"6069 W STUDIO CT\",\"City\":\"LOS ANGELES\",\"State\":\"CA\",\"Zipcode\":\"\"}
]"
]
The code that is throws the error is the following:
var addressesInternal = new List<RequestAddressInternal>();
addresses.ToList().ForEach(x =>
{
addressesInternal.Add(new RequestAddressInternal()
{
InternalAddressKey = Guid.NewGuid().ToString(),
RequestAddress = x
});
});
Addresses is defined like so:
RequestAddress[] addresses
// Defined in a Model class:
public class RequestAddress
{
public string CustomerAddressKey { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
}
RequestAddressInternal looks like this:
public class RequestAddressInternal
{
public string InternalAddressKey { get; set; }
public RequestAddress RequestAddress { get; set; }
}
The error I get back from the web service is this:
{
"Message": "An error has occurred.",
"ExceptionMessage": "This document already has a 'DocumentElement' node.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at System.Xml.XmlDocument.IsValidChildType(XmlNodeType type)\r\n at System.Xml.XmlNode.AppendChild(XmlNode newChild)\r\n at Newtonsoft.Json.Converters.XmlNodeWrapper.AppendChild(IXmlNode newChild)\r\n at Newtonsoft.Json.Converters.XmlNodeConverter.CreateElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, String elementName, XmlNamespaceManager manager, String elementPrefix, Dictionary`2 attributeNameValues)\r\n at Newtonsoft.Json.Converters.XmlNodeConverter.ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, String propertyName, XmlNamespaceManager manager)\r\n at Newtonsoft.Json.Converters.XmlNodeConverter.DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, String propertyName, IXmlNode currentNode)\r\n at Newtonsoft.Json.Converters.XmlNodeConverter.DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode)\r\n at Newtonsoft.Json.Converters.XmlNodeConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)\r\n at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)\r\n at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)\r\n at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonConverter[] converters)\r\n at Newtonsoft.Json.JsonConvert.DeserializeXmlNode(String value, String deserializeRootElementName, Boolean writeArrayAttribute)\r\n at Midas.WebApi.waCarrierServiceabilityLib.CarrierServiceabilityImpl.ProcessBulkImpl(String serviceRequest, String clientId, String clientRequestTrackingId, RequestAddress[] addresses, String clientOwner, String uid, String ipAddress, Boolean includeGeodata) in E:\\Source Code\\GitHub\\waCarrierServiceability\\waCarrierServiceabilityLib\\CarrierServiceabilityImpl.cs:line 222\r\n at Midas.WebApi.waCarrierServiceabilityLib.CarrierServiceabilityImpl.ProcessBulk(String serviceRequest, JArray requestRaw, String clientId, String clientOwner, String userId, String ipAddress, Boolean includeGeodata) in E:\\Source Code\\GitHub\\waCarrierServiceability\\waCarrierServiceabilityLib\\CarrierServiceabilityImpl.cs:line 134\r\n at Midas.WebApi.waCarrierServiceability.Controllers.CarrierServiceabilityController.GetCarrierServiceabilityBulk(JArray jsonParamList) in E:\\Source Code\\GitHub\\waCarrierServiceability\\Controllers\\CarrierServiceability.cs:line 120\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}
At this point I'm wondering if it's some time type of threading issues? I wrapped the code that is the last to execute in a try catch and caught exception, however no exception was thrown, it just never makes it to the next line in the code.

I'm not able to give a complete answer unfortunately, but having a look, a couple of things that might be worth trying:
It looks potentially that the Json parsing to get your input string to the array addresses might be failing (so that when you get to this stage in the code, it's not the two parsed Json strings you're expecting). You could try setting a break point on this line in the debugger, and checking what addresses is equal to?
Sometimes with LINQ it can be tricky to see what's going on until after the lambda call (x => ...) has been returned. To get around this you can set a temporary variable:
var temp = addresses.ToList();
and then you can use this value to check what happens with the first element in the list temp, if you apply the following steps in your code. Stepping through with the debugger may help to see where the error is coming in?
Again apologies that this is just a list of possible ideas, but hope you're able to solve your problem!

Related

Ninject Serilization error when calling new StandardKernel

When I try to call
var ninjectKernel = new StandardKernel();
I get the below error. I can successfully use ninject with constructor injection. I only get this error when I try to grab a service by hand.
{"Message":"An error has occurred.","ExceptionMessage":"Type
'Ninject.Web.WebApi.NinjectDependencyResolver' in assembly
'Ninject.Web.WebApi, Version=3.3.1.0, Culture=neutral,
PublicKeyToken=c7192dc5380945e7' is not marked as
serializable.","ExceptionType":"System.Runtime.Serialization.SerializationException","StackTrace":"
at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName,
String typeName)\r\n at
Ninject.Modules.AssemblyNameRetriever.GetAssemblyNames(IEnumerable1 filenames, Predicate1 filter)\r\n at
Ninject.Modules.CompiledModuleLoaderPlugin.LoadModules(IEnumerable1 filenames)\r\n at Ninject.Modules.ModuleLoader.LoadModules(IEnumerable1 patterns)\r\n
at Ninject.KernelBase.Load(IEnumerable1 filePatterns)\r\n at Ninject.KernelBase..ctor(IComponentContainer components, INinjectSettings settings, INinjectModule[] modules)\r\n at Ninject.KernelBase..ctor(INinjectModule[] modules)\r\n at Ninject.StandardKernel..ctor(INinjectModule[] modules)\r\n at Controllers.Controllers.TagController.GetTags(TagEnum tagType) in C:\\Users\\george\\Desktop\\NewScp\\SCP\\UI\\Controllers\\TagController.cs:line 39\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary2 arguments, CancellationToken
cancellationToken)\r\n--- End of stack trace from previous location
where exception was thrown ---\r\n at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task)\r\n at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task)\r\n at
System.Web.Http.Controllers.ApiControllerActionInvoker.d__1.MoveNext()\r\n---
End of stack trace from previous location where exception was thrown
---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task)\r\n at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task)\r\n at
System.Web.Http.Controllers.ActionFilterResult.d__5.MoveNext()\r\n---
End of stack trace from previous location where exception was thrown
---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task)\r\n at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task)\r\n at
System.Web.Http.Dispatcher.HttpControllerDispatcher.d__15.MoveNext()"}

ITfoxtec.Identity.Saml2 Invalid URI Issue

When i use <TargetFramework>net462</TargetFramework> for my Okta SAML implementation this throw a Invalid URL when it this new Saml2AuthnRequest(config); but on my first try using this code on netcoreapp3.1` this worked perfectly fine. Please let me know if i miss something thank you.
[HttpGet, AllowAnonymous]
public IActionResult Index(string returnUrl = null)
{
try
{
var config = GetSAMLConfig();
var binding = new Saml2RedirectBinding();
binding.SetRelayStateQuery(new Dictionary<string, string> { { relayStateReturnUrl, returnUrl ?? Url.Content("~/") } });
var request = new Saml2AuthnRequest(config);
return binding.Bind(request).ToActionResult();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private Saml2Configuration GetSAMLConfig()
{
var config = new Saml2Configuration();
config.AllowedAudienceUris.Add("Okta_SAML_Example");
config.CertificateValidationMode = X509CertificateValidationMode.ChainTrust;
config.RevocationMode = X509RevocationMode.NoCheck;
var entityDescriptor = new EntityDescriptor();
entityDescriptor.ReadIdPSsoDescriptorFromUrl(new Uri("https://---------.okta.com/app/exk2b0b7dibno7rOB5d6/sso/saml/metadata"));
if (entityDescriptor.IdPSsoDescriptor != null)
{
config.SingleSignOnDestination = entityDescriptor.IdPSsoDescriptor.SingleSignOnServices.First().Location;
config.SignatureValidationCertificates.AddRange(entityDescriptor.IdPSsoDescriptor.SigningCertificates);
}
else
{
throw new Exception("IdPSsoDescriptor not loaded from metadata.");
}
return config;
}
Actual exception
System.UriFormatException: Invalid URI: The format of the URI could not be determined.
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at ITfoxtec.Identity.Saml2.Configuration.Saml2IdentityConfiguration.GetAudienceRestriction(Boolean audienceRestricted, IEnumerable`1 allowedAudienceUris)
at ITfoxtec.Identity.Saml2.Configuration.Saml2IdentityConfiguration.GetIdentityConfiguration(Saml2Configuration config)
at ITfoxtec.Identity.Saml2.Saml2Request..ctor(Saml2Configuration config)
at ITfoxtec.Identity.Saml2.Saml2AuthnRequest..ctor(Saml2Configuration config)
at SAMLNet461.Controllers.HomeController.Index(String returnUrl) in D:\REPO\PELICAN\LOCAL\SAML.RND - CompanyAcccounts adjustment\SAML.Demo\SAMLNet461\Controllers\HomeController.cs:line 69
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeInnerFilterAsync>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResourceFilter>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__16.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
The code looks correct.
Maybe it is a TLS version issue.
An alternative solution is to download the metadata in your code and add the metadata string to the ITfoxtec Identity SAML 2.0 library:
var idPMetadataXml = "... downloaded metadata ...";
var entityDescriptor = new EntityDescriptor();
entityDescriptorReadIdPSsoDescriptor(idPMetadataXml);
...
Updated:
The error seams to be in relation to Audience Restriction:
config.AllowedAudienceUris.Add("Okta_SAML_Example");
The audience have to be a URI in a .NET Framework application. Plain text strings are only supported in .NET Core and .NET 5.0.
.NET Framework sample: https://github.com/ITfoxtec/ITfoxtec.Identity.Saml2/tree/master/test/TestWebApp
I had the same issue and it was caused by "GetAudienceRestriction() method". Changing issuer name from "application-name" to "https://application-name" helped. Don't forget to change your name on your Identity Provider side (Okta, Ping Identity etc.) consistently. Now exception is not thrown anymore.

Forward ASP.Net WebAPI request to another API

I am trying to forward request from one API to another one like this:
protected Task<HttpResponseMessage> ForwardRequestToSomeApi()
{
string forwardUri = "https://some.api" + Request.RequestUri.PathAndQuery;
Request.Headers.Remove("Host");
Request.RequestUri = new Uri(forwardUri);
if (Request.Method == HttpMethod.Get)
{
Request.Content = null;
}
return new HttpClient().SendAsync(Request, HttpCompletionOption.ResponseHeadersRead);
}
but when sending PUT request I get:
Cannot close stream until all bytes are written.
Full exception info:
{"Message":"An error has occurred.","ExceptionMessage":"An error occurred while sending the request.","ExceptionType":"System.Net.Http.HttpRequestException","StackTrace":"
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__1`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"The request was aborted: The request was canceled.","ExceptionType":"System.Net.WebException","StackTrace":"
at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting)\r\n
at System.Net.ConnectStream.System.Net.ICloseEx.CloseEx(CloseExState closeState)\r\n
at System.Net.ConnectStream.Dispose(Boolean disposing)\r\n
at System.IO.Stream.Close()\r\n
at System.Net.Http.HttpClientHandler.<>c__DisplayClass109_0.<GetRequestStreamCallback>b__0(Task task)","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Cannot close stream until all bytes are written.","ExceptionType":"System.IO.IOException","StackTrace":"
at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting)"}}}
Inner exception :
IOException Message: "Cannot close stream until all bytes are
written." StackTrace: at
System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean
aborting)
Update:
Provided above code is fully working, the problem was how I attempted to use it. In my main API I had next webapi action:
[HttpPut]
public Task<HttpResponseMessage> Create(string id, Foo model)
{
return ForwardRequestToSomeApi();
}
The problem here is I introduced the model in parameters, thanks to model binding request's content were being read and parsed into model, so when I forward request to another API I send request without content. The fix is to remove all parameters:
[HttpPut]
public Task<HttpResponseMessage> Create()
{
return ForwardRequestToSomeApi();
}

Splitting a string throws InvalidOperationException when hosting on IIS

I wrote the following code:
private string makeMailContents(Klant klant, Mail mail)
{
var builder = new BodyBuilder();
var path = Path.Combine("wwwroot/trackers/track_open.png");
var img = builder.LinkedResources.Add(path);
byte[] data = Convert.FromBase64String(mail.Content);
string decoded = Encoding.UTF8.GetString(data);
string code;
string final = "";
Regex regex = new Regex(#"\[([^]]*)\]");
img.ContentId = MimeUtils.GenerateMessageId();
var splitContent = decoded.Split(' ');
foreach(string word in splitContent) // this is line 265
{
if (word.Contains('[') && word.Contains(']'))
{
try
{
code = Regex.Match(word, #"\[([^]]*)\]").Groups[1].Value.ToLower();
switch (code)
{
case "voornaam":
final += regex.Replace(word, klant.vnaam) + ' ';
break;
case "achternaam":
final += regex.Replace(word, klant.anaam) + ' ';
break;
case "naam":
final += regex.Replace(word, klant.vnaam + ' ' + klant.anaam + ' ');
break;
case "onderwerp":
final += regex.Replace(word, mail.Onderwerp + ' ');
break;
case "datum":
final += regex.Replace(word, DateTime.Now.ToString("dd-MM-yyyy") + ' ');
break;
}
}
catch (Exception ex)
{
final += ex;
}
}
else
{
final += word + ' ';
}
}
}
Whenever I run this code on my local machine and my test server it executes the code like it should without any exceptions.
But whenever I host this on my current live server it throws the following exception:
InvalidOperationException: Sequence contains no elements
And this exceptions keeps pointing towards the splitContent and it tells me that it doesn't contain elements. And yes, the mail.Content is filled with a valid base64 string, I checked both with fiddler and postman.
Does anyone have the slightest clue of what's going on here? I'm also not sure if it's the IIS settings or somehow my code. I normally have a colleague who manages the IIS but he is on vacation right now. Can someone help me out with this?
This is the data the mail receives when called:
{
"Onderwerp":"Dit is een test campagne",
"afzender":1,
"campagne":1,
"Content":"PHA+RGl0IGlzIGVlbiB0ZXN0IG1hYXQ8L3A+Cg==",
"docs":"['kamer2.jpg']",
"template":null,
"verzenddat":"8/17/18, 3:55 PM"
}
full exception:
System.InvalidOperationException: Sequence contains no elements
at System.Linq.Enumerable.Last[TSource](IEnumerable`1 source)
at lambda_method(Closure , QueryContext )
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass17_1`1.<CompileQueryCore>b__0(QueryContext qc)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Last[TSource](IQueryable`1 source)
at MailerAPI.Mailer.Sender.makeMailContents(Klant klant, Mail mail) in C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Mailer\Sender.cs:line 265
at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
at MailerAPI.Mailer.Sender.<sendMessage>d__7.MoveNext() in C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Mailer\Sender.cs:line 161
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MailerAPI.Controllers.MailController.<Post>d__13.MoveNext() in C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Controllers\MailController.cs:line 96
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeInnerFilterAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
The exception also gets thrown when I replace the model properties with just a plain string.
UPDATE
Whenever I run this code in my values controller to test the decoded.split(' ') it actually works. When I return the decoded.split(' ') I actually get an array of strings.
So now I know that the problem only occurs within the method, which is located in a Sender class and being called in the MailerController, and it also only occurs in the current server.
You appear to be making a call to .Last() at or through the code located at C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Mailer\Sender.cs:line 265.
The Linq extension method .Last() demands that there is at least one item that it can grab. To work around this requirement, you have various options:
use .LastOrDefault() accompanied with appropriate null handling, or
before using .Last(), first check with if (... .Any()) if it is OK to call .Last().
For further reference, see LINQ Element Operations

Sendgrid Inbound Web Hook using Web API C Sharp

I am trying to parse emails coming in from send grid using the web hook feature but just get the below error...
"An error has occurred.","ExceptionMessage":"Unexpected character encountered while parsing number: W. Path '', line 1, position 6.","ExceptionType":"Newtonsoft.Json.JsonReaderException","StackTrace":" at Newtonsoft.Json.JsonTextReader.ReadNumberCharIntoBuffer(Char currentChar, Int32 charPos)\r\n at Newtonsoft.Json.JsonTextReader.ReadNumberIntoBuffer()\r\n at Newtonsoft.Json.JsonTextReader.ParseNumber(ReadType readType)\r\n at Newtonsoft.Json.JsonTextReader.ParseValue()\r\n at Newtonsoft.Json.JsonTextReader.Read()\r\n at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)\r\n at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)\r\n at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)\r\n at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonConverter[] converters)\r\n at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonConverter[] converters)\r\n at StrongGrid.WebhookParser.ParseWebhookEvents(String requestBody) in C:\projects\stronggrid\Source\StrongGrid\WebhookParser.cs:line 48\r\n at WebAPI_InboundMail.Controllers.HomeController.d__0.MoveNext() in C:\Dev\Baxter Personnel\Projects\Comms\WebAPI_InboundMail\WebAPI_InboundMail\Controllers\HomeController.cs:line 23\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Threading.Tasks.TaskHelpersExtensions.d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"}
Here is my code, any help be great...
[HttpPost]
public async Task<IHttpActionResult> Post()
{
var requestBody = await Request.Content.ReadAsStringAsync();
var parser = new WebhookParser();
var events = parser.ParseWebhookEvents(requestBody);
bool status = true;
var response = status == true? new HttpResponseMessage(HttpStatusCode.OK) : new HttpResponseMessage(HttpStatusCode.BadRequest);
return Ok("");
}
Based on the error message (which is Unexpected character encountered while parsing number), it sounds like the WebhookParser in the StrongGrid library is trying to parse a given value into a number but the value in the Json sent by SendGrid is not numerical.
Can you look at the content of your requestBody variable and detect which property is causing the issue? If you post the content of your variable I'll try to help.

Categories