Override or alias field name in ServiceStack.Text without DataContract - serialization

Using this method: Override field name deserialization in ServiceStack I am able to override field names. Is there an alternative where I don't have to use DataContract? I'd like to be opt-out serialization.
Edit: as stated in comments below, this is not available by design to match the rest of .NET.

You can use [IgnoreDataMember] to make it opt out and omit adhoc fields.

Related

Spring Data Rest Make an Entity Read Only by Default

I have an API exposed via Spring Data Rest which, for the most part, is read-only but which allows for updating of some properties via PATCH requests.
Is there any (I'm supposing Jackson) configuration at a global level that would essentially make an entity read only unless specific properties were annotated in some way.
I am familiar with the#JsonProperty(access = Access.READ_ONLY) Jackson annotation however would like to avoid having to annotate all read-only properties.
For example, given the class below only the field explicitly annotated would be writable. All other fields would be readable by default:
public class Thing{
private String fieldOne;
#JsonProperty(access = Access.READ_WRITE)
private String fieldTwo;
private String fieldThree;
// a lot of other properties
}
Failing any global configuration, is there anything that can be applied at the class level?
I am not aware of any way to globally set all attributes in a class to read only. Since version 2.6+ of FaserXML you can use the following annotation to at least defined the set of properties you would ignore and only allow for serialization. The following annotation would be used at the class level:
#JsonIgnoreProperties(value={ "fieldOne", "fieldThree"}, allowGetters=true)
It is not exactly what you are looking for, but arguably makes coding a little easier.

How do I determine the WCF namespace from a PropertyInfo?

I'm writing an implementation of IWsdlExportExtension and I've collected a list of PropertyInfo instances that need their corresponding XSD declarations to be modified. In order to do this, I need to determine their XML namespace.
I understand that looking at the DataMemberAttribute is not enough. Is there a built in method in the WCF libraries that can provide that information? Otherwise, would the algorithm look like to determine this?
I believe what you want is get an instance of the ContractDescription class. This class has a namespace property.
You can get an instance of this class using one of the GetContract methods. They have a Type parameter. So In your case, you could use this kind of call:
string myNamespace = ContractDescription.GetContract(
typeof(IMyService),
myPropertyInfo.DeclaringType).Namespace;
NOTE: you will also need the contract type (represented in this sample by typeof(IMyService))

Adding protobuff-net serialization to WCF through code with knowntypes

I currently have all of my WCF connections defined in code and I'm trying to shoehorn protobuff-net serialization in with little success. None of my contracts are marked with the knowntype attribute as we have a base message with a payload (it would be dozens of knowntypes). We figure out the knowntypes we have and cache them in a class derived from DataContractSerializerOperationBehavior. Then in the overridden CreateSerializer function I pass the cached known types into the DataContractSerializer as follows
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
new DataContractSerializer(type, name, ns, m_Known ?? knownTypes, 0x7FFF, ...)
}
Is there some way to pass a list of known types to the protobuf-net serializer. I realize protobuf-net isn't meant to mirror the serializers for WCF, but it would be nice if they followed the pattern for allowing overriding the knowntypes list. Thanks for any help.
However I don't have the option to treat the Protobuf-net serializer this way (I looked at the ProtoOperationBehavior). Is there anyway to not have known types specified in the
In "v2", the available subtypes can be defined (against a RuntimeTypeModel) on the fly at runtime via .AddSubType(...) (in fact, all the attributes now only serve as a default configuration for the type-model, which can be configured any which way).
However, I should stress that v2 is currently in beta, and as noted in the blog the WCF hooks are currently not included in the beta, purely while I finish validation etc. However, I expect that with your setup as shown in the question it should be trivial (it will merely be a case of passing the model into the XmlObjectSerializer implementation provided).

DataContract attribute -WCF

Is DataContract attribute is deprecated in ASP.NET 4.0 WCF ? I can see only DataContractFormat attribute.
I can't apply DataContractFormat attribute over struct.
example
[DataContractFormat]
public struct Contact
{
public string firstName;
public string lastName;
}
It throws an error saying that DataContractFormat artribute can only be used on class, interface and methods.
No, the .NET 4 still contains the DataContractAttribute:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute%28v=VS.100%29.aspx
and it should be able to be applied to class or struct.
You have to add a reference to the System.Runtime.Serialization assembly (right click References, add ref...)
DataContract is not deprecated - where the heck did you get that idea from?
DataCOntractFORMAT is something totally different. I suggest you please read the documentation ;) Helps a lot. Will also explain what DataContractFormat is for.
http://msdn.microsoft.com/en-us/library/system.servicemodel.datacontractformatattribute.aspx
As you can see in the example this attribute goes on the class/interface that defines the SERVICE CONTRACT. It controls how for that service data serializaton is (guess what) formatted.

WCF MessageContract Inheritance

I am fairly new to WCF and just have a question on how to correctly get MessageContract inheritance working. A simplified version of my setup is as follows - a "base" message type, and then another "test" message which inherits from it.
[MessageContract]
public abstract class BaseMessage
{ }
[MessageContract]
public class TestMessage : BaseMessage
{ }
I then have an asynchronous OperationContract on a ServiceContract defined as:
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginFindRequest(BaseMessage request, AsyncCallback callback, object asyncState);
The problem that I am getting is when calling the BeginFindRequest method, and passing in a TestMessage instance for the request parameter, the WCF framework is deserialising the TestMessage instance to BaseMessage on the service/server side. As this is defined as an abstract class, it results in the following error:
"The message cannot be deserialized
into MessageContract type BaseMessage
since it does not have a default
(parameterless) constructor."
From the limited information that I can find on MessageContract inheritance, it seems that it should just work.
So my question is - what am I missing in order to get this to work; or should I perhaps rather define a seperate OperationContract on the ServiceContract specifically for that type - the downside being that I could end up with many additional OperationContracts?
In the end I found this blog post which hit the nail on the head -
Unfortunately the way that contracts
are expressed in WCF makes is very
easy to forget what their purpose is:
to define the messages send to the
operation and being sent back from the
operation. In reality you have to
think “how would I express this data
in XML?”. XML doesn’t support
inheritance so whatever you put in the
contract is going to have to have some
way of mapping to XML. The data
contracts used to define the messages
are simply a .NET typed convenience
for generating the XML for the data
you want to pass – if you view them
any other way you are destined for a
world of pain. So think about the data
you want to pass, not how it may
happen to be represented in your
business layer and design your
DataContracts accordingly.
http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,a3775eb1-b441-43ad-b9f1-e4aaba404235.aspx
So I will be refactoring to provide an additional method with an explicit contract type. This will also allow me to clean up the service implementation by removing all the type checking.
Thanks for the assistance.
OK, first question is: why are you really using Message contracts? Do you really have a need for that??
Typically, message contracts are only ever used when you need to tightly control the layout of your SOAP message, e.g. to satisfy a legacy system you need to call which requires specific headers and such.
A "normal" WCF call should hardly ever need to use a message contract.
You define your service calls (the methods on your service) using [ServiceContract], and the data structures being passed around as [DataContract]. If you have a DataContract, you have more options as to how to deal with inheritance / polymorphism in your service (more than with the message contract construct).
Marc
Is that possible to change BaseMessage so that it is concrete class with parameterless constructor?
The error message tells that there is no way to initialize the object of type BaseMessage because it is abstract.
The error simply wants you to have a default empty contructor that it can use. However, I agree with marc_s; in the projects I've worked on I've rarely used message contract, the only case I can remember was as part of a file transfer service where file chunks were passed in messasges.
Try decorating your [ServiceContract] with the KnownType attribute. Since TestMessage is not 'visible' from a public operation, this helps the plumbing know how to treat it when it sees it.
If this should allow the [DataContract] to be serialized as a TestMessage your still likely to need to handle multiple messages differently via 'is a' or some other casting.
Well I had declared this default (parameterless) constructor for sure, but that was not still working fine for me, for me the issue was, the access modifier was protected while it should be public:
public constructor() { }
^^^^