NServicebus Nhibernate Exception on sending message - nhibernate

When we send a message through NServiceBus containing a full exception stacktrace we get the following NHibernate exception:
Z Error dehydrating property value for
NServiceBus.TimeoutPersisters.NHibernate.TimeoutEntity.Headers NHibernate.PropertyValueException NHibernate.HibernateException NServiceBus.Core
at NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.ProcessMessage(TransportMessage m)
at NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.ReceiveMessage()
at NServiceBus.Utils.TransactionWrapper.RunInTransaction(Action callback, IsolationLevel isolationLevel, TimeSpan transactionTimeout)
at NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.Process()
It has something to do with the length of the message field, but it seems like it's an internal
NServiceBus issue. We use NServiceBus v3.2.4
The message class looks like this:
public class ExceptionOccuredCommand : ICommand
{
public string Message { get; set; }
public string Details { get; set; }
public DateTime ExceptionDate { get; set; }
public string UserName { get; set; }
public string MachineName { get; set; }
public string ApplicationName { get; set; }
public string ErrorQueue { get; set; }
//public string SourceQueue { get; set; }
public string MessageId { get; set; }
}
How can this be fixed?

There is a hard limit on 4000 characters for the headers and you seems to be hitting that limit. I've opened up an issue for this on our issues list: https://github.com/NServiceBus/NServiceBus/issues/737

Related

SignalR (asp.net core) not sending Complex class object

SignalR for some reason fails when I try to send an object from client to be represented in a complex class.
The below client-side code works fine...
connection.send("ABC", "111", "222", { text: "text" }).then(() => console.log("sent")).catch((r) => console.log(r))
...for the below server-side code
public async Task ABC(string a, string b, User c)
{
await Clients.All.SendAsync(RECEIVE, a, b, c);
}
public class User
{
public string Text { get; set; }
public string Name { get; set; }
}
The below doesn't work....
connection.send("ABC", "111", "222", { text: "text", jsonOptions: [] }).then(() => console.log("sent")).catch((r) => console.log(r))
...for the below server side code
public async Task ABC(string a, string b, Post c)
{
await Clients.All.SendAsync(RECEIVE, a, b, c);
}
public class Post
{
public int Id { get; set; }
[Required] [StringLength(450, ErrorMessage = "Sender id cannot be more than 450")]
public string SenderId { get; set; }
[Required] [StringLength(30, ErrorMessage = "Sender name cannot be more than 30")]
public string SenderName { get; set; }
[StringLength(300, ErrorMessage = "Senderpic length must not be more than 300")]
public string SenderPic { get; set; }
public PostLocation PostLocation { get; set; }
public int? CourseId { get; set; }
public int ClassId { get; set; }
public int? ChatId { get; set; }
public int? LectureId { get; set; }
[Required] [StringLength(2000, ErrorMessage = "Post text cannot be more than 2000")]
public string Text { get; set; }
[Required]
public DateTimeOffset TimeStamp { get; set; }
[NotMapped]
public int Upvotes { get; set; }
[NotMapped]
public ICollection<string> UpvoteIds { get; set; }
[NotMapped]
public ICollection<string> DownvoteIds { get; set; }
[NotMapped]
public ICollection<string> StarredIds { get; set; }
public PostType Type { get; set; }
public bool IsReply { get; set; }
[ForeignKey(nameof(FullRepliedPost))]
public int? RepliedId { get; set; }
[NotMapped]
public MiniPost RepliedPost { get; set; }
[StringLength(300, ErrorMessage = "ProfilePicturePath length must not be more than 300")]
public string AttachmentPath { get; set; }
public AttachmentType AttachmentType { get; set; }
public int AnsweredPostId { get; set; }
public Choice CorrectAnswer { get; set; }
public string JsonOptions { get; set; }
[NotMapped]
public ICollection<string> Options => (ICollection<string>)
JsonConvert.DeserializeObject(JsonOptions, typeof(ICollection<string>));
[NotMapped]
public ICollection<string> ASelectionIds { get; set; }
[NotMapped]
public ICollection<string> BSelectionIds { get; set; }
[NotMapped]
public ICollection<string> CSelectionIds { get; set; }
[NotMapped]
public ICollection<string> DSelectionIds { get; set; }
[NotMapped]
public ICollection<string> ESelectionIds { get; set; }
#region navigation properties
[JsonIgnore]
public Post FullRepliedPost { get; set; }
[JsonIgnore]
public ICollection<PostVote> PostVotes { get; set; }
[JsonIgnore]
public ICollection<PostStar> PostStars { get; set; }
[JsonIgnore]
public ICollection<MultiChoice> OptionSelections { get; set; }
[JsonIgnore] [ForeignKey(nameof(RepliedId))]
public ICollection<Post> Replies { get; set; }
#endregion
}
I use the above Post class as a business object, that's why it has all those attributes. I wonder if that has something to do with the failure. I get the below error in Chrome dev tools
[2020-11-07T20:19:42.768Z] Information: Connection disconnected.
and when I try to send again, I get an error saying that I can't send messages when signalR is disconnected.
EDIT: I omitted something in the code I pasted here (jsonOptions: []), which turned out to be the actual cause of the problem.
It turns out the problem was entirely my fault. The JsonOptions property in the entity class should be a string, but I was sending an array from the client. Replacing jsonOptions: [] with jsonOptions: "[]" fixed it and it serialized fine.
Regardless, I've decided to just send the Id of the Post object instead of the whole object. I think it's going to be more efficient that way.

The new ASP.NET Core 3.0 Json serializer is leaving out data

I'm porting a web application to ASP.NET Core 3, and after a bit of a battle, I'm almost at the finish line. Everything seems to work, but all of a sudden my JSON data returned from the api is missing some levels.
It seems the options.JsonSerializerOptions.MaxDepth is default at 64 levels, so it can be that. Some other places where an option can be playing tricks on me?
This is the code (and a quickview of the value):
And this is the JSON I get in the browser:
So the ParticipantGroups property/collection is completely missing in the generated output.
Any ideas where this happens?
EDIT:
I've added a repo on Github that showcases the issue. Standard ASP.NET Core 3.0 solution, created from the template, with a change to the result returned from the Weatherforecast controller:
https://github.com/steentottrup/systemtextjsonissue
For now I've gone back to using Newtonsoft.Json, with the Microsoft.AspNetCore.Mvc.NewtonsoftJson package. Then when I have some time, I'll try finding out what the solution is, without Newtonsoft.Json.
The problem seems to be an error in the new version 3.0. At least it seems like an error to me.
It seems System.Text.Json will convert the class mentioned in the hierarchy, not the actual class. So if you are using an abstract class in the hierarchy, you're in trouble. The second I removed the base class, and used the actual class I'm returning, the problem goes away it seems.
So this doesn't work:
public class SurveyReportResult {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
public IEnumerable<OrganisationalUnit> OrganisationalUnits { get; set; }
}
public abstract class OrganisationalUnit {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
}
public class OrganisationalUnitWithParticipantGroups : OrganisationalUnit {
public IEnumerable<ParticipantGroup> ParticipantGroups { get; set; }
}
public class ParticipantGroup {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
}
This will only return the properties of the OrganisationalUnit class, not the additional property of the OrganisationalUnitWithParticipantGroups.
This works:
public class SurveyReportResult {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
public IEnumerable<OrganisationalUnitWithParticipantGroups> OrganisationalUnits { get; set; }
}
public class OrganisationalUnitWithParticipantGroups /*: OrganisationalUnit*/ {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
public IEnumerable<ParticipantGroup> ParticipantGroups { get; set; }
}
public class ParticipantGroup {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 MemberCount { get; set; }
}

I am using complex type as datamember of a datacontract

I am using complex type as datamember of a datacontract. But the service is throwing an exception if i set [DataMember] to the complextype. What might be the reason. KIndly suggest. Below is the code snippet
[DataContract]
public class GetDetailsFromCardNumberResponseBody
{
public GetDetailsFromCardNumberResponseBody()
{
}
public GetDetailsFromCardNumberResponseBody
(PatronAccountCardValidation GetDetailsFromCardNumberResult)
{
this.GetDetailsFromCardNumberResult = GetDetailsFromCardNumberResult;
}
[DataMember]
public PatronAccountCardValidation GetDetailsFromCardNumberResult { get; set; }
}
[DataContract(Name="PatronAccountCardValidation")]
public class PatronAccountCardValidation
{
[DataMember]
public Patron Patron { get; set; }
[DataMember]
public Card Card { get; set; }
[DataMember]
public string BonusDollarLocal { get; set; }
[DataMember]
public string BonusDollarRemote { get; set; }
[DataMember]
public bool Valid { get; set; }
[DataMember]
public string MessageText { get; set; }
}
Check the parameter PatronAccountCardValidation.
Check property Card. It is causing an issue. Please help.
Error received:
An unhandled exception of type
'System.ServiceModel.CommunicationException' occurred in mscorlib.dll
Additional information: An error occurred while receiving the HTTP
response to localhost:9090/DoorAccessAndVendingMachineService. This
could be due to the service endpoint binding not using the HTTP
protocol. This could also be due to an HTTP request context being
aborted by the server (possibly due to the service shutting down). See
server logs for more details
Have you consider to apply Data Contract Know types? It allows you to specify, in advance, the types that should be included for consideration during deserialization. And by default during deserialization, an uninitialized object is first created, without calling any constructors on the type. Then all data members are deserialized. See more details here.
[DataContract]
[KnownType(typeof(PatronAccountCardValidation))]
public class GetDetailsFromCardNumberResponseBody
{
public GetDetailsFromCardNumberResponseBody()
{
}
public GetDetailsFromCardNumberResponseBody
(PatronAccountCardValidation GetDetailsFromCardNumberResult)
{
this.GetDetailsFromCardNumberResult = GetDetailsFromCardNumberResult;
}
[DataMember]
public PatronAccountCardValidation GetDetailsFromCardNumberResult { get; set; }
}
[KnownType(typeof(Card))]
[KnownType(typeof(Patron))]
[DataContract(Name="PatronAccountCardValidation")]
public class PatronAccountCardValidation
{
[DataMember]
public Patron Patron { get; set; }
[DataMember]
public Card Card { get; set; }
[DataMember]
public string BonusDollarLocal { get; set; }
[DataMember]
public string BonusDollarRemote { get; set; }
[DataMember]
public bool Valid { get; set; }
[DataMember]
public string MessageText { get; set; }
}

MVC4 Mailgun delivered webhook

I'm having an issue making use of the Mailgun delivered webhook, it can be found here: http://documentation.mailgun.net/user_manual.html#events-webhooks, look for "Delivered Event Webhook"
I am unable to reference Request.Params["Message-Id"] unless I modify the app's requestValidationMode to 2.0
I do get the potentially unsafe error when trying to reference this field without requestValidationMode = 2.0. The contents of the field are: <20130203200110.12345.12345#mydomain.mailgun.org>. I've also tried to declare a model to take advantage of auto model binding. My model looks like this:
public class MailgunDeliveredEvent
{
public string Id { get; set; }
public string Event { get; set; }
public string Recipient { get; set; }
public string Domain { get; set; }
[AllowHtml]
[JsonProperty(PropertyName="Message-Id")]
public object MessageId { get; set; }
public int Timestamp { get; set; }
public string Token { get; set; }
public string Signature { get; set; }
}
When I attempt to reference the MessageId field it returns null. I've tried to add
[Bind(Exclude="message-headers")]
As I'm not interested in that field.
In the Controller, I've set
[ValidateInput(false)]
I can't seem to get the Message-Id field back. Any help?
I seem to have got it working, in case anyone runs into the same issue...
I added a new model binder as referenced here:
Asp.Net MVC 2 - Bind a model's property to a different named value
I then changed my model like so:
[ModelBinder(typeof(DefaultModelBinderEx))]
public class MailgunDeliveredEvent
{
public string Id { get; set; }
public string Event { get; set; }
public string Recipient { get; set; }
public string Domain { get; set; }
[BindAlias("Message-Id")]
public string MessageId { get; set; }
public int Timestamp { get; set; }
public string Token { get; set; }
public string Signature { get; set; }
}
And all seems to work, I didn't need to call
[ValidateInput(false)]
on the controller either.
Hope that helps someone.

How to add a couple of million documents to RavenDB - Embedded

I have installed the latest embedded binaries from NuGet and am using this code to store a 'product' poco. After a bit, the process dies with an OutOfMemoryException. Is storing this much data out of scope for Raven?
Thank you.
Stephen
var store = new EmbeddableDocumentStore { DataDirectory = #"C:\temp\ravendata", UseEmbeddedHttpServer = true };
store.Initialize();
using (var session = store.OpenSession())
{
foreach (var item in Parsers.GetProducts().ToList())
{
session.Store(item);
}
session.SaveChanges();
//var rdbList = session.Query<Product>().ToList();
}
[Serializable]
public class Product
{
public decimal ProductId { get; set; }
public string ItemNum { get; set; }
public string ProductName { get; set; }
public string BrandName { get; set; }
public string UOM { get; set; }
public string AveWeight { get; set; }
public string CasePack { get; set; }
public string PackageRemarks { get; set; }
public decimal Price { get; set; }
public string SupplierName { get; set; }
public string Url { get; set; }
public bool IsSpecialOrderItem { get; set; }
public bool IsSpecialPriceItem { get; set; }
public bool IsRebateItem { get; set; }
public bool IsTieredPricingItem { get; set; }
public bool IsOfflineSupplierItem { get; set; }
public string Catalog { get; set; }
public decimal CatalogId { get; set; }
public decimal CategoryId { get; set; }
public decimal PriceGroupId { get; set; }
public decimal OffineSupplierId { get; set; }
public string ManufactureName { get; set; }
public string ManufactureNum { get; set; }
public string Upc { get; set; }
public string Info { get; set; }
public string INFO2 { get; set; }
}
How big of a batch are you doing? It looks like people have success with 256 batch sizes. Seems like much more causes timeouts and memory exceptions.
*EDIT: It sounds like it is also recommended to make a new session per batch so as to not keep the session open too long which can cause timeout errors.
No, RavenDB is perfectly fine with this amount of data. Unless you don't RunInMemory an EmbeddedDocumentStore is pretty much the same as a standalone server, just without the http overhead and direct access to the database from the client.
Given your code, you want to make sure that you store your documents in batches, e.g. 1024 for each session. Another thing you want to make sure is, that your GetProducts() method returns an IEnumerable and yields the items in a proper ETL way of doing things.