MassTransit with AWS SQS - exception sending dynamic message - asp.net-core

I'm using Masstransit with AWS SQS/SNS as a transport.
Now I'm stuck with a simple problem - adding CorrelationId to published message. Since I'm following recommendation to use interfaces as DTOs, so I can't use CorrelatedBy<Guid> interface and I decided to add __CorrelationId property to messages directly.
I'm using following wrapper to publish message:
public class MessageBus : IMessageBus
{
// ... omitted for brevity
public async Task Publish<T>(object message)
where T : class
{
await this.publishEndpoint.Publish<T>(this.CreateCorrelatedMessage(message));
}
private object CreateCorrelatedMessage(object message)
{
dynamic corellatedMessage = new ExpandoObject();
foreach (var property in message.GetType().GetProperties())
{
((IDictionary<string, object>)corellatedMessage).Add(property.Name, property.GetValue(message));
}
corellatedMessage.__CorrelationId = this.correlationIdProvider.CorrelationId;
return corellatedMessage;
}
}
And here is the usage:
await this.messageBus.Publish<ObtainRequestToken>(new
{
Social = SocialEnum.Twitter,
AppId = credentials.First(x => x.Name == "TwitterConsumerKey").Value,
AppSecret = credentials.First(x => x.Name == "TwitterConsumerSecret").Value,
ReturnUrl = returnUrl
});
This works well in console app with following bus registration:
var busControl = Bus.Factory.CreateUsingAmazonSqs(cfg =>
{
cfg.Host("eu-west-1", h =>
{
h.AccessKey("xxx");
h.SecretKey("xxx");
h.Scope($"Local", scopeTopics: true);
});
});
But is ASP.NET Core application with
services.AddMassTransit(cfg =>
{
cfg.UsingAmazonSqs((context, sqsCfg) =>
{
var amazonAccount = this.Configuration
.GetSection("AmazonAccount")
.Get<AmazonAccountConfig>();
sqsCfg.Host(amazonAccount.Region, h =>
{
h.AccessKey(amazonAccount.KeyId);
h.SecretKey(amazonAccount.SecretKey);
h.Scope(this.Environment.EnvironmentName, scopeTopics: true);
});
});
cfg.SetEndpointNameFormatter(new DefaultEndpointNameFormatter(this.Environment.EnvironmentName + "_", false));
});
services.AddMassTransitHostedService();
It fails on publish with Object reference not set to an instance of an object. and stacktrace
at MassTransit.Logging.EnabledDiagnosticSource.StartSendActivity[T](SendContext1 context, ValueTuple2[] tags)
at MassTransit.AmazonSqsTransport.Transport.TopicSendTransport.SendPipe1.<Send>d__5.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at GreenPipes.Agents.PipeContextSupervisor1.<GreenPipes-IPipeContextSource<TContext>-Send>d__7.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at GreenPipes.Agents.PipeContextSupervisor1.<GreenPipes-IPipeContextSource<TContext>-Send>d__7.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at GreenPipes.Agents.PipeContextSupervisor1.<GreenPipes-IPipeContextSource<TContext>-Send>d__7.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at MassTransit.Initializers.MessageInitializer2.<Send>d__9.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at MassTransit.Transports.PublishEndpoint.<>c__DisplayClass18_01.<<PublishInternal>g__PublishAsync|0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
at xxx.Main.Api.Messaging.MessageBus.<Publish>d__51.MoveNext() in D:\repo\projects\xxx\mainapi\xxx.Main.Api\Messaging\MessageBus.cs:line 34
StartSendActivity looks like simple diagnostics method and I can't fugure out, what can be failing there.

You can't send object or other types like that with MassTransit. Messages must be reference types.
Relevant Documentation

Related

Duplicate type name within an assembly in Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware

I have .NET Core 1.1 API and i am handling the error in startup.cs as below. I am using Serilog
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime, IRequestContext requestContext)
{
loggerFactory.AddSerilog();
// Ensure any buffered events are sent at shutdown
appLifetime.ApplicationStopped.Register(Log.CloseAndFlush);
var logger = loggerFactory.CreateLogger<Startup>();
app.UseExceptionHandler(
options =>
{
options.Run(
async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var ex = context.Features.Get<IExceptionHandlerFeature>();
if (ex != null)
{
var errmsg = "An unexpected error has occured in API.";
var logDetails = new
{
CorrelationId = requestContext.CorrelationId,
Message = errmsg
};
logger.LogError(1001, ex.Error, "{#LogDetails}", logDetails);
await context.Response.WriteAsync(errmsg).ConfigureAwait(false);
}
});
});
app.UseMvc();
logger.LogInformation("Application has started in environment {0}", env.EnvironmentName);
}
Most of the time when there is any exception, Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware logs the exception as expected however, sometimes i see the following exception in the logs
2018-09-21 18:36:01.670 +00:00 [Error] An unhandled exception has
occurred: Duplicate type name within an assembly.
System.ArgumentException: Duplicate type name within an assembly.
at System.Reflection.Emit.ModuleBuilder.CheckTypeNameConflict(String
strTypeName, Type enclosingType) at
System.Reflection.Emit.AssemblyBuilderData.CheckTypeNameConflict(String
strTypeName, TypeBuilder enclosingType) at
System.Reflection.Emit.TypeBuilder.Init(String fullname,
TypeAttributes attr, Type parent, Type[] interfaces, ModuleBuilder
module, PackingSize iPackingSize, Int32 iTypeSize, TypeBuilder
enclosingType) at
System.Reflection.Emit.ModuleBuilder.DefineType(String name,
TypeAttributes attr, Type parent, Type[] interfaces) at
Microsoft.Extensions.DiagnosticAdapter.Internal.ProxyAssembly.DefineType(String
name, TypeAttributes attributes, Type baseType, Type[] interfaces)
at
Microsoft.Extensions.DiagnosticAdapter.Internal.ProxyTypeEmitter.GenerateProxyTypeFromProperties(Type
sourceType, Type targetType, VerificationResult verificationResult)
at
Microsoft.Extensions.DiagnosticAdapter.Internal.ProxyTypeEmitter.VerifyProxySupport(ProxyBuilderContext
context, Tuple2 key) at
Microsoft.Extensions.DiagnosticAdapter.Internal.ProxyTypeEmitter.GetProxyType(ProxyTypeCache
cache, Type targetType, Type sourceType) at
Microsoft.Extensions.DiagnosticAdapter.Internal.ProxyFactory.CreateProxy[TProxy](Object
obj) at Proxy_Method_From_<>f__AnonymousType03_To_Void
OnBeforeAction(Microsoft.AspNetCore.Http.HttpContext,
IRouteData)(Object , Object , IProxyFactory ) at
Microsoft.Extensions.DiagnosticAdapter.DiagnosticSourceAdapter.Write(String
diagnosticName, Object parameters) at
Microsoft.Extensions.DiagnosticAdapter.DiagnosticSourceAdapter.System.IObserver>.OnNext(KeyValuePair`2
value) at System.Diagnostics.DiagnosticListener.Write(String
name, Object value) at
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__20.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.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.Diagnostics.ExceptionHandlerMiddleware.d__6.MoveNext()
So looks like Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware its selft throwing exception while logging
Update 1
I have the following references. Not sure which reference is causing this issue.
Microsoft.ApplicationInsights.AspNetCore is 2.0 however the only options available for this package are 1.0.* or 2.*.*. I don't see this package has 1.1.* available

Unit testing using Fakes gives IConvertible exception

What I have
The interface:
public interface IDocDbRepository
{
Task<JObject> UpdateDocumentAsync(JObject updatedDocument);
}
The implementation:
public async Task<JObject> UpdateDocumentAsync(JObject updatedDocument)
{
if (updatedDocument == null)
{
throw new ArgumentNullException(nameof(updatedDocument));
}
var response = await this.documentDBClient.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(this.dbName, this.collectionName, updatedDocument["id"].Value<string>()), updatedDocument).ConfigureAwait(false);
return JObject.Parse(response.Resource.ToString());
}
The exception occurs in the await line.
The Unit Test:
static Guid docGuid = Guid.NewGuid();
[TestMethod]
public async Task TestMethod2()
{
var jObject = new JObject { { "id", docGuid }, { "studentId", "1" }, { "courseId", "Ph" } };
// Arrange
var docClient = new ShimDocumentClient();
ShimDocumentClient.AllInstances.CreateDocumentAsyncUriObjectRequestOptionsBoolean =
(instance, uri, document, options, disableAutomaticGeneration) => Task.FromResult(new ResourceResponse<Document>(new Document() { Id = docGuid.ToString() }));
// Act
var documentRepository = new DocDbRepository(endPointUri, accountKey, dbName, collectionName);
try{
var response = await documentRepository.UpdateDocumentAsync(jObject).ConfigureAwait(false);
}
catch(Exception ex){}
// Assert
Assert.AreEqual(response.Count, 1);
}
The test does not go beyond the UpdateDocumentAsync part and exits with this message:
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Newtonsoft.Json.Linq.Extensions.Convert[T,U](T token)
at Newtonsoft.Json.Linq.Extensions.Value[T,U](IEnumerable`1 value)
at Newtonsoft.Json.Linq.Extensions.Value[U](IEnumerable`1 value)
at Common.DataAccess.DocumentDb.DocDbRepository.<UpdateDocumentAsync>d__12.MoveNext() in C:\Common\Common.DataAccess.DocumentDb\DocDbRepository.cs:line 196
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Common.DataAccess.DocumentDb.Tests.DocDbUtilityTests.<TestMethod2>d__9.MoveNext() in C:\Common\Common.DataAccess.DocumentDb.Tests\DocDbUtilityTests.cs:line 113
This is my first time with Fakes framework.
Any help is greatly appreciated.
Thanks in advance.
Regards.
This appears to be a problem with your serialization code. Specifically, this statement:
updatedDocument["id"].Value<string>()
The Value extension method appears to require that the source implement the IConvertible interface, which is not implemented by Guid.

Unexpected end of stream at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream

System.IO.IOException: Unexpected end of stream.
at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.<ReadAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.<DrainAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.WebUtilities.MultipartReader.<ReadNextSectionAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at AspNetCoreFileUpload.Controllers.FileUploadController.<Index>d__0.MoveNext()
in C:\\GitHub\\StackOverflow\\LargeFileUploadController\\FileUploadController.cs:line 29
Repro: https://github.com/bigfont/StackOverflow/tree/master/LargeFileUploadController
Form
<form action = ""/FileUpload"" method=""post"" enctype=""multipart/form-data"">
<label for=""myfile1"">File</label>
<input type=""file"" name=""myFile1"" />
<label for=""myfile2"">File</label>
<input type=""file"" name=""myFile2"" />
<input type=""submit"" value=""Send"" />
</form>
Controller
public class FileUploadController : Controller
{
[HttpPost]
public async Task<IActionResult> Index()
{
var boundary = GetBoundary(Request.ContentType);
var reader = new MultipartReader(boundary, Request.Body);
try
{
var section = await reader.ReadNextSectionAsync();
}
catch (System.Exception ex)
{
return new OkObjectResult(new { ex = ex.ToString() });
}
return new OkObjectResult(new { message = "Done" });
}
private static string GetBoundary(string contentType)
{
var elements = contentType.Split(' ');
var element = elements.Where(entry => entry.StartsWith("boundary=")).First();
var boundary = element.Substring("boundary=".Length);
// Remove quotes
if (boundary.Length >= 2 &&
boundary[0] == '"' && boundary[boundary.Length - 1] == '"')
{
boundary = boundary.Substring(1, boundary.Length - 2);
}
return boundary;
}
}
I got almost the same exception recently. I'm saying almost because they actually renamed the exception to Unexpected end of Stream, the content may have already been read by another component., which actually means that something already consumed the body stream. The comments of the following change gives us the understanding of what's happening:
Tratcher commented on Mar 23
...The MVC model binder reads the form and buffers the multipart segments
for you, so there's no point in re-parsing request body with the
MultipartReader...
So, the question is how to disable the default form binding (reading the request form)?
I found the DisableFormValueModelBindingAttribute attribute in this Mvc.FileUpload sample which disables the form binding and this is what it looks like:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var formValueProviderFactory = context.ValueProviderFactories
.OfType<FormValueProviderFactory>()
.FirstOrDefault();
if (formValueProviderFactory != null)
{
context.ValueProviderFactories.Remove(formValueProviderFactory);
}
var jqueryFormValueProviderFactory = context.ValueProviderFactories
.OfType<JQueryFormValueProviderFactory>()
.FirstOrDefault();
if (jqueryFormValueProviderFactory != null)
{
context.ValueProviderFactories.Remove(jqueryFormValueProviderFactory);
}
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
If you want some more information, you can check out the following:
Create a filter/sample that shows how to remove the form value providers (rynowak opened this issue on Apr 26)
Sample: Issues with Antiforgery + Form + File Uploads (rynowak opened this issue on Apr 26)
Just for info - as commented before, the MVC model binder reads the form, but where can one find the results. The results can be found in the HttpRequest.Form, which has Files.
Don't know if this might help you but I came across simular issue "Unexpected end of Stream, the content may have already been read by another component".
app.Use(async (context, next) => {
context.Request.EnableRewind();
await next();
});
Code above were added in Startup.cs Configure method.
Hope it helps
I created a MemoryStream, copied stream from body there and it was working like a charm :) Point is you cannot read Stream twice. However, this is not a case for MemoryStream. Of course, you have to be sure about scaling, I don't think this will work for really big files uploaded. I didn't tested this.
I rewrote example from Microsoft site: enter link description here
Here is part of it:
while (section != null)
{
ContentDispositionHeaderValue contentDisposition;
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
if (hasContentDispositionHeader)
{
if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
{
var ms = new MemoryStream();
var fileSection = section.AsFileSection();
await fileSection.FileStream.CopyToAsync(ms);
ms.Position = 0;
documentUpload.Attachments.Add(new SimpleFileInstance { FileName = fileSection.FileName, FileStream = ms });
}
else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
{
// Content-Disposition: form-data; name="key"//
// value
// Do not limit the key name length here because the
// multipart headers length limit is already in effect.
var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;
var encoding = GetEncoding(section);
using (var streamReader = new StreamReader(
section.Body,
encoding,
detectEncodingFromByteOrderMarks: true,
bufferSize: 1024,
leaveOpen: true))
{
// The value length limit is enforced by MultipartBodyLengthLimit
var value = await streamReader.ReadToEndAsync();
if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
{
value = string.Empty;
}
formAccumulator.Append(key, value);
if (formAccumulator.ValueCount > DefaultFormOptions.ValueCountLimit)
{
throw new InvalidDataException($"Form key count limit {DefaultFormOptions.ValueCountLimit} exceeded.");
}
}
}
}
section = await reader.ReadNextSectionAsync();
}
documentUpload is our DTO to work further with files. In our case, some documents gets uploaded to SharePoint.

MassTransit 2.10.0 cause LockRecursionException

I'm running into an issue where LockRecursionException is thrown (occasionally) when sending a message in MassTransit via RabbitMq.
System.Threading.LockRecursionException: Write lock may not be acquired with read lock held. This pattern is prone to deadlocks
The exception is raised in the class MassTransit.Transports.DefaultConnectionPolicy, and it looks like the Execute method gets the read lock, runs a callback and always releases the read lock via a finally block. However, for whatever reason the callback raise a InvalidConnectionException and the code try to Reconnect(). The Reconnect() will try to get the write lock in TryEnterWriteLock and ends up with System.Threading.LockRecursionException as read lock is already being hold by the current thread. I'm unable to see how could that possibly happen given the Finally block should release the read lock, unless the ExitReadLock is not doing what it suppose to do.
I've included the full class from the MassTransit source code and full stack trace.
public class DefaultConnectionPolicy : ConnectionPolicy
{
readonly ConnectionHandler _connectionHandler;
readonly TimeSpan _reconnectDelay;
readonly ILog _log = Logger.Get(typeof(DefaultConnectionPolicy));
readonly ReaderWriterLockSlim _connectionLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public DefaultConnectionPolicy(ConnectionHandler connectionHandler)
{
_connectionHandler = connectionHandler;
_reconnectDelay = 10.Seconds();
}
public void Execute(Action callback)
{
try
{
try
{
// wait here so we can be sure that there is not a reconnect in progress
_connectionLock.EnterReadLock();
callback();
}
finally
{
_connectionLock.ExitReadLock();
}
}
catch (InvalidConnectionException ex)
{
_log.Warn("Invalid Connection when executing callback", ex.InnerException);
Reconnect();
if (_log.IsDebugEnabled)
{
_log.Debug("Retrying callback after reconnect.");
}
try
{
// wait here so we can be sure that there is not a reconnect in progress
_connectionLock.EnterReadLock();
callback();
}
finally
{
_connectionLock.ExitReadLock();
}
}
}
void Reconnect()
{
if (_connectionLock.TryEnterWriteLock((int)_reconnectDelay.TotalMilliseconds/2))
{
try
{
if (_log.IsDebugEnabled)
{
_log.Debug("Disconnecting connection handler.");
}
_connectionHandler.Disconnect();
if (_reconnectDelay > TimeSpan.Zero)
Thread.Sleep(_reconnectDelay);
if (_log.IsDebugEnabled)
{
_log.Debug("Re-connecting connection handler...");
}
_connectionHandler.Connect();
}
catch (Exception)
{
_log.Warn("Failed to reconnect, deferring to connection policy for reconnection");
_connectionHandler.ForceReconnect(_reconnectDelay);
}
finally
{
_connectionLock.ExitWriteLock();
}
}
else
{
try
{
_connectionLock.EnterReadLock();
if (_log.IsDebugEnabled)
{
_log.Debug("Waiting for reconnect in another thread.");
}
}
finally
{
_connectionLock.ExitReadLock();
}
}
}
}
And the full stack trace
An exception was thrown during Send ---> System.Threading.LockRecursionException: Write lock may not be acquired with read lock held. This pattern is prone to deadlocks. Please ensure that read locks are released before taking a write lock. If an upgrade is necessary, use an upgrade lock in place of the read lock.
at System.Threading.ReaderWriterLockSlim.TryEnterWriteLockCore(TimeoutTracker timeout)
at System.Threading.ReaderWriterLockSlim.TryEnterWriteLock(TimeoutTracker timeout)
at MassTransit.Transports.DefaultConnectionPolicy.Reconnect() in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Transports\DefaultConnectionPolicy.cs:line 75
at MassTransit.Transports.DefaultConnectionPolicy.Execute(Action callback) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Transports\DefaultConnectionPolicy.cs:line 53
at MassTransit.Transports.ConnectionPolicyChainImpl.Next(Action callback) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Transports\ConnectionPolicyChainImpl.cs:line 49
at MassTransit.Transports.ConnectionHandlerImpl`1.Use(Action`1 callback) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Transports\ConnectionHandlerImpl.cs:line 86
at MassTransit.Transports.RabbitMq.OutboundRabbitMqTransport.Send(ISendContext context) in z:\Builds\work\4ed32a1c3fc3f594\src\Transports\MassTransit.Transports.RabbitMq\OutboundRabbitMqTransport.cs:line 51
at MassTransit.Transports.Transport.Send(ISendContext context) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Transports\Transport.cs:line 50
at MassTransit.Transports.Endpoint.Send[T](ISendContext`1 context) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Transports\Endpoint.cs:line 111
--- End of inner exception stack trace ---
at MassTransit.Transports.Endpoint.Send[T](ISendContext`1 context) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Transports\Endpoint.cs:line 117
at MassTransit.Pipeline.Sinks.EndpointMessageSink`1.<Enumerate>b__0(IBusPublishContext`1 x) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Pipeline\Sinks\EndpointMessageSink.cs:line 45
at MassTransit.Pipeline.Sinks.OutboundConvertMessageSink`1.<>c__DisplayClass2.<>c__DisplayClass4.<Enumerate>b__1(ISendContext x) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Pipeline\Sinks\OutboundConvertMessageSink.cs:line 36
at MassTransit.ServiceBus.Publish[T](T message, Action`1 contextCallback) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\ServiceBus.cs:line 180
--- End of inner exception stack trace ---
at MassTransit.ServiceBus.Publish[T](T message, Action`1 contextCallback) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\ServiceBus.cs:line 207
at MassTransit.Context.BusObjectPublisherImpl`1.Publish(IServiceBus bus, Object message, Action`1 contextCallback) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\Context\BusObjectPublisherImpl.cs:line 30
at MassTransit.ServiceBus.Publish(Object message, Type messageType, Action`1 contextCallback) in z:\Builds\work\4ed32a1c3fc3f594\src\MassTransit\ServiceBus.cs:line 244
at CollectionHouse.MassTransit.Messaging.MassTransitMessageBus.PublishImmediate(Object message)
at CollectionHouse.MassTransit.Services.MassTransitPublisher.Publish(Object message)
at CollectionHouse.MicroBus.EventBroadcast.MessageBroadcastHandler.<Handle>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Enexure.MicroBus.PipelineBuilder.<>c__DisplayClass7_0.<<GenerateNext>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at CollectionHouse.MicroBus.PipelineHandlers.LoggingHandler.<Handle>d__3.MoveNext()

How to create a SecondaryTile on Windows Phone 8.1?

I'm trying to create a Tile on the Windows Phone start screen. The following code used to work but now it doesn't. I didn't change anything.
private async static void CreateTile()
{
try
{
SecondaryTile tileData = new SecondaryTile()
{
TileId = "MyTileID",
DisplayName = "My App Name",
TileOptions = TileOptions.ShowNameOnLogo,
};
tileData.VisualElements.Square150x150Logo = new Uri("ms-appx:///Resources/Images/Tiles/150150.png", UriKind.Absolute);
tileData.VisualElements.ShowNameOnSquare150x150Logo = true;
await tileData.RequestCreateAsync();
}
catch (Exception ex)
{
}
}
Now it's failing with the error message:
The parameter is incorrect.
and the following Stack Trace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at My.Namespace.SplashPage.<CreateTile>d__f.MoveNext()
I even get the error when I comment everything out, for example:
SecondaryTile tileData = new SecondaryTile()
{
//TileId = "MyTileID",
//DisplayName = "My App Name",
//TileOptions = TileOptions.ShowNameOnLogo,
};
//tileData.VisualElements.Square150x150Logo = new Uri("ms-appx:///Resources/Images/Tiles/150150.png", UriKind.Absolute);
//tileData.VisualElements.ShowNameOnSquare150x150Logo = true;
await tileData.RequestCreateAsync();
So I don't know what parameter is incorrect. What could be causing this? How can I fix it?
Try something like this:
if (SecondaryTile.Exists(tileID)) await tileData.UpdateAsync();
else await tileData.RequestCreateAsync();