When XML is replaced by JSON, it is because of the smaller file size of the JSON.
Now that you're on your cell phone, the JSON packets are becoming more unacceptable. All you have is a JSON property name, and the real useful attribute value is only a small part of the entire JSON package. If you can not "attribute name", it is very good, but that is not possible.
I have heard of PROTOBUF, and have not used it for a long time. These two days have been spent studying for a while, successfully applied on the server side (WEBAPI) and the client (Xamarin.form).
Put two pictures first to feel:
Can be much smaller, and the specific class structure and data integrity. But from the comparison of the results alone, the effect is really attractive!
If you apply it to your mobile phone, you can elevate your app experience by more than one grade!
1, declaration of the service-side entity class (WEBAPI):
NuGet---protobuf-net, to an an-release version.
At first, I installed the WEBAPICONTRIB.FORMATTING.PROTOBUF directly, incidentally installing the Protobuf-net 2.0.0.448 version, resulting in a loop-referenced entity set escalation error:
Possible recursion detected.
Why is there a circular reference? Have you ever used EF? Searched a circle, have said what Protobuf only supports the Tree, does not support the graph.
Json.NET serialization, you can set loopreferences = Ignore, if PROTOBUF does not support such a function, it is really degrading Google's teeth.
Later saw Asreferencedefault this thing, knocked a bit, do not have this attribute, only meaning to download the version is too old.
Data entity definition on the server side:
1[Protocontract (Asreferencedefault =true, Implicitfields =Implicitfields.allfields)]2 Public Partial classT_branch3 {4 Public decimalbranch_id {Get;Set; }5 6 Public stringBranch_code {Get;Set; }7...
The effect of implicitfields.allfields is equal to adding protomember to each attribute.
2, register PROTOBUF format device
Add in Global:
1 GlobalConfiguration.Configuration.Formatters.Add (new protobufformatter ());
Source code for Protobufformatter:
1 Public classProtobufformatter:mediatypeformatter {2 Private Static ReadOnlyMediatypeheadervalue mediatype =NewMediatypeheadervalue ("Application/x-protobuf");3 Private StaticLazy<runtimetypemodel> model =NewLazy<runtimetypemodel>(Createtypemodel);4 5 Public StaticRuntimetypemodel Model {6 Get {7 returnmodel. Value;8 }9 }Ten One PublicProtobufformatter () { A Supportedmediatypes.add (mediatype); - } - the Public Staticmediatypeheadervalue Defaultmediatype { - Get { - returnmediatype; - } + } - + Public Override BOOLcanreadtype (Type type) { A returnCanreadtypecore (type); at } - - Public Override BOOLcanwritetype (Type type) { - returnCanreadtypecore (type); - } - in Public Overridetask<Object>readfromstreamasync (type type, stream stream, httpcontent content, Iformatterlogger formatterlogger) { - varTCS =Newtaskcompletionsource<Object>(); to + Try { - Objectresult = Model.deserialize (stream,NULL, type); the TCS. Setresult (result); *}Catch(Exception ex) { $ TCS. SetException (ex);Panax Notoginseng } - the returnTCS. Task; + } A the Public OverrideTask writetostreamasync (Type type,Objectvalue, Stream stream, httpcontent content, TransportContext transportcontext) { + varTCS =Newtaskcompletionsource<Object>(); - $ Try { $ Model.serialize (stream, value); -Tcs. Setresult (NULL); -}Catch(Exception ex) { the TCS. SetException (ex); - }Wuyi the returnTCS. Task; - } Wu - Private StaticRuntimetypemodel Createtypemodel () { About varTypemodel =typemodel.create (); $Typemodel.useimplicitzerodefaults =false; - returnTypemodel; - } - A Private Static BOOLcanreadtypecore (Type type) { + return true; the } -}
View Code
At this point, the server is finished, you can request a trial effect. Remember to add the request header: Accept, the value is: application/x-protobuf
3, PCL entity class
In general, I will separate the data entities (POCO) into a single class library, which makes it easy for individual projects to use because these Poco class libraries do not involve any business logic.
Now, on the phone side encountered a problem, with these class libraries, the data received on the server to deserialize, whether it is JSON or PROTOBUF, will be error.
Following up, it is all because: add to the Serializable on the class; Added to attributes such as the Required/stringlength attribute. Because these features are not supported in the PCL class library.
It's impossible to get rid of these things.
If it is based on the Dbfirst/modelfirst EF class library, that good, add a corresponding PCL class library, the original library of the TT template copy to a PCL library, change it.
If it's a Codefirst class library, it's a little bit complicated:
1, or create a corresponding PCL class library.
2, copy all the class files from the original library to the PCL class library.
3. Add a attributes directory that will redefine all of the properties in the class library that are not supported by the PCL, such as Stringlengthattribute:
1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Linq;4 usingSystem.Text;5 usingSystem.Threading.Tasks;6 7 namespace System.ComponentModel.DataAnnotations {8 Public classStringlengthattribute:attribute {9 Ten PublicStringlengthattribute (intmax) { One } A - } -}
Note that the namespace must be the same as the original.
4, take these PCL class libraries instead of the original library, used in the phone.
4, the Protobuf class library of the mobile terminal
Protobuf-net is a PCL version, except that the protobuf-net added in NuGet cannot be installed in the PCL library, you need to download the protobuf-net first, and then add the references manually:
Do not add non-PCL version of the protobuf-net to the PCL class library, run will error.
5, WebApi Client settings
1, add the above ProtoBufFormatter.cs to the PCL class library on the phone side.
2, use Protobufformatter in the Readasasync method:
1 varA =await This. GetResult (token);2 varReason ="";3HttpStatusCode? Status =NULL;4 if(A! =NULL) {5 if(a.issuccessstatuscode) {6 if( This. SUPPORTPROTOBUF) {7 return awaitA.content.readasasync<t> (New[] {New protobufformatter () });8}Else9 return awaitA.content.readasasync<t>();Ten}Else { OneReason =a.reasonphrase; AStatus =A.statuscode; - } -}
For details, please refer to:
Https://github.com/gruan01/LbcTest/blob/master/Lbc.WebApi/MethodBase.cs
OK, the above is the whole process of using protobuf in Xamarin.form.
Use PROTOBUF in Xamarin.form to enhance your app's experience