Is there a way to debug the ModelBinding? - servicestack

I am using ServiceStack and am having difficulty with one of my Request DTOs. One of the properties of type int is always coming through as 0 even though I can see it set correctly in the request.
Is there a method of debugging the ModelBinding process within ServiceStack?

Related

How can I make JAXB to fail when a mandatory element is missing?

I'm trying to add some forward compatibility to a Java application calling a Web Service at work, but JAXB seems to behave backward on the subject...
The application use the wsdl2java Maven plugin to generate a CXF Web Service client from a WSDL. It then uses that generated client to communicate with a Web Service (through SOAP over JMS).
When the Web Service sends an unknown element in its response to a call, JAXB fails with an "unexpected element" error, which is understandable, and XML-compliant. To be more forward compatible, I specified a custom jaxb-reader-validation-event-handler to ignore those specific errors, which solved the problem.
But while doing some complementary tests, I discovered non-XML-compliant behaviours.
First, JAXB doesn't care about elements' order, even inside a sequence, which is not XML-compliant, but good for forward compatibility, so why not.
However, it also doesn't care if a mandatory element (minOccurs="1") is not present, kindfully assigning it an arbitrary default value (which is, for elements bound to Java primitive values, their default values, like 0 for an int!).
This is both non-XML-compliant and not good for compatibility: if you need a mandatory, say, price as an integer, but the Web Service doesn't provide it for some reason, JAXB assigns the value 0 to it without a warning, making debugging really hard.
Apparently it's because if JAXB doesn't encounter an element, it simply doesn't call its setter, which means it will keep its default value.
[EDIT: I made some complementary tests, and when the application expect 1 element (maxOccurs="1") but the Web Service sends 2, JAXB calls the same setter two times, overriding the first value with the second, so it seems that once the client is generated from the WSDL, minOccurs and maxOccurs are simply ignored...]
How can I make JAXB to fail when a mandatory element is missing?
We noticed that, even for an element with minOccurs="1", the annotation of the corresponding generated attribute does not contain required = true. I tried to add it manually after the generation and before starting the application, but with no success: it seems it's simply ignored...
Maybe an additional JSR–303 validation covers what you want to achieve. You may either extend xjc’s behavior with a plugin like: https://github.com/krasa/krasa-jaxb-tools to have your binding classes annotated, or use Hibernate Validator in conjunction with XML validation config as described here: https://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html/validator-xmlconfiguration.html#validator-xmlconfiguration

"Error: this process has called an NSArray-taking method..." when iCloud pushes managed objects

For every managed object that is sent via iCloud update, this warning/error is sent to the console:
*** ERROR: this process has called an NSArray-taking method, such as
initWithArray:, and passed in an NSSet object. This is being
worked-around for now, but will soon cause you grief.
My managed objects are Clients and have a one to many relationship with assessments as shown below.
class Client: NSManagedObject {
//other NSManaged vars are here
#NSManaged var assessment: NSOrderedSet
}
Judging by the timing of this error (during ubiquitous updates) and the fact that this is my only use of NSSet objects in my project, I can presume that a function during this update is being passed an NSOrderedSet when its expecting an NSArray.
Turning off iCloud removes the errors.
I found two other folks with a very similar issue:
Using iCloud enabled Core Data NSArray-taking method
Core Data Relation between Objects
However, neither offers any solution to my problem. Everything is working fine right now, however "it will soon cause you grief."
If this isn't resolved here, I'll take this issue up with the apple dev support.
I figured it out how to fix this error after much research. (No help in from the Apple Dev forums).
This is error is caused by the Swift 1.2 upgrade. They encourage you to use their new Set<> class instead of NSSet. The error was a vague way of reinforcing that claim.
Ordering of my data was ultimately handled by my NSFetchedResultsController, so I didn't need the stored data to be ordered. So I set out on a task to change the data type for my one to many relationship from NSOrderedSet to Set.
So I created a new data model, selected my relationship and unchecked "Ordered" in the data model inspector. Then migrated to the new model in the next run. (as shown below)
Once that was done, I changed the data type in my managed object subclass from NSOrderedSet to Set. (or Set). That generated compiler errors that were easy to fix throughout my code.
The new Set class easily converts to an array: Array(mySet)
To insert an object to the set, there's an easy insert method. foo.mySet.insert(objectToInsert).
Side note: Converting my relationship to a Set also fixed some weird ordering issues I was having with my table views and the NSFetchedResultsController.
Then I ran the program, generated data, uninstalled the program. Ran the program again and watch the glorious iCloud data populate without the annoying errors.
Boom. I hope this saves someone out there the 10 hours of turmoil (I tried a lot of different things..) I spent to fix this.

Antlr4 parser not handling custom token types

I am migrating my grammar from version 3 to 4. I recognize that version 4 has listeners and visitors and I plan to use them, but hope to do the migration piece meal. I want to leave actions intact in my grammar for the time being.
I am using a custom token, and specify it using TokenLabelType in the option section of the grammar. However, the generated code uses a 'match()' method which doesn't get promoted to my custom token, causing the java compilation to fail.
I also noticed the 'start' property of a token is not promoted to the custom token type either.
Is there something else I should do to properly use custom tokens in my code?
If memory serves, Ter posted a design document on the Antlr.org site that outlines the differences between Antlr3 and 4 (cannot seem to find it at the moment).
In any case, make sure your custom token extends org.antlr.v4.runtime.CommonToken. The supported Antlr4 Action attributes are listed here. The start attribute is valid on a parser rule, but not on a token.
Note also that many of the token fields, including start, are protected. There are, however, corresponding getters defined in CommonToken -- start accessed by getStartIndex().

IOneWay SOAP Parameters and Void Return

I'm having a couple of issues with getting a correct WSDL generated for a ServiceStack SOAP+REST service.
The main issue is that when I use AddServiceReference the generated IOneWay is populated and the methods all return void. Looking at the provided SOAP examples it looks like ISyncReply should be populated (currently no operations at all) and the response type should be one of the fields in the DTO + Response object. What am I doing wrong?
The types and operations are distributed across multiple namespaces
but they are all referenced with a single ContractNamespace in AssemblyInfo
The DTO + Response naming convention has been followed
I thought it might be an issue with inherited Request/Response types, but even cutting them out completely doesn't change the situation, though apparently you can't inherit from a concrete type even from within a named namespace and have the operation parameters be generated properly
Using explicit [DataContract]/[DataMember] annotations does not make a difference
REST calls seem to be working as expected
I'm using the latest ServiceStack binaries
The WSDL does not have wsdl:output elements at all
Applies both SOAP 1.1 and SOAP 1.2 wsdls
And just to complicate the situation still further the metadata produced in http://*/metadata for each operation seems to be completely accurate!!
Let me know if there is any specific further information I can provide.

Preventing StackOverflowException while serializing Entity Framework object graph into Json

I want to serialize an Entity Framework Self-Tracking Entities full object graph (parent + children in one to many relationships) into Json.
For serializing I use ServiceStack.JsonSerializer.
This is how my database looks like (for simplicity, I dropped all irrelevant fields):
I fetch a full profile graph in this way:
public Profile GetUserProfile(Guid userID)
{
using (var db = new AcmeEntities())
{
return db.Profiles.Include("ProfileImages").Single(p => p.UserId == userId);
}
}
The problem is that attempting to serialize it:
Profile profile = GetUserProfile(userId);
ServiceStack.JsonSerializer.SerializeToString(profile);
produces a StackOverflowException.
I believe that this is because EF provides an infinite model that screws the serializer up. That is, I can techincally call: profile.ProfileImages[0].Profile.ProfileImages[0].Profile ... and so on.
How can I "flatten" my EF object graph or otherwise prevent ServiceStack.JsonSerializer from running into stack overflow situation?
Note: I don't want to project my object into an anonymous type (like these suggestions) because that would introduce a very long and hard-to-maintain fragment of code).
You have conflicting concerns, the EF model is optimized for storing your data model in an RDBMS, and not for serialization - which is what role having separate DTOs would play. Otherwise your clients will be binded to your Database where every change on your data model has the potential to break your existing service clients.
With that said, the right thing to do would be to maintain separate DTOs that you map to which defines the desired shape (aka wireformat) that you want the models to look like from the outside world.
ServiceStack.Common includes built-in mapping functions (i.e. TranslateTo/PopulateFrom) that simplifies mapping entities to DTOs and vice-versa. Here's an example showing this:
https://groups.google.com/d/msg/servicestack/BF-egdVm3M8/0DXLIeDoVJEJ
The alternative is to decorate the fields you want to serialize on your Data Model with [DataContract] / [DataMember] fields. Any properties not attributed with [DataMember] wont be serialized - so you would use this to hide the cyclical references which are causing the StackOverflowException.
For the sake of my fellow StackOverflowers that get into this question, I'll explain what I eventually did:
In the case I described, you have to use the standard .NET serializer (rather than ServiceStack's): System.Web.Script.Serialization.JavaScriptSerializer. The reason is that you can decorate navigation properties you don't want the serializer to handle in a [ScriptIgnore] attribute.
By the way, you can still use ServiceStack.JsonSerializer for deserializing - it's faster than .NET's and you don't have the StackOverflowException issues I asked this question about.
The other problem is how to get the Self-Tracking Entities to decorate relevant navigation properties with [ScriptIgnore].
Explanation: Without [ScriptIgnore], serializing (using .NET Javascript serializer) will also raise an exception, about circular
references (similar to the issue that raises StackOverflowException in
ServiceStack). We need to eliminate the circularity, and this is done
using [ScriptIgnore].
So I edited the .TT file that came with ADO.NET Self-Tracking Entity Generator Template and set it to contain [ScriptIgnore] in relevant places (if someone will want the code diff, write me a comment). Some say that it's a bad practice to edit these "external", not-meant-to-be-edited files, but heck - it solves the problem, and it's the only way that doesn't force me to re-architect my whole application (use POCOs instead of STEs, use DTOs for everything etc.)
#mythz: I don't absolutely agree with your argue about using DTOs - see me comments to your answer. I really appreciate your enormous efforts building ServiceStack (all of the modules!) and making it free to use and open-source. I just encourage you to either respect [ScriptIgnore] attribute in your text serializers or come up with an attribute of yours. Else, even if one actually can use DTOs, they can't add navigation properties from a child object back to a parent one because they'll get a StackOverflowException.
I do mark your answer as "accepted" because after all, it helped me finding my way in this issue.
Be sure to Detach entity from ObjectContext before Serializing it.
I also used Newton JsonSerializer.
JsonConvert.SerializeObject(EntityObject, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });

Resources