core
core copied to clipboard
No ability to define custom rules of json serialization
And its hard to undestand how websharper decodes/encodes json data. For example These data
{ "user": "sdf", "pass": "zxczxc" }
are recognized correctly to object of this type:
type UserPass = { user: string; pass : string }
but if we change the order of the properties in the json object like this:
{ "pass": "zxczxc", "user": "sdf" }
we get just NoEncodingException
This definitely looks like a bug, it should work regardless of the field order.
I can't seem to reproduce the issue, the following works correctly here:
type EndPoint =
| [<EndPoint "POST /"; Json "userpass">] Home of userpass: UserPass
and UserPass = { user: string; pass : string }
[<Website>]
let Main =
Application.MultiPage (fun ctx (EndPoint.Home userpass) ->
Content.Text(sprintf "%s : %s" userpass.user userpass.pass)
)
My code is more complicated because I can not use the syntax of named fields in the discrimanated unions on the target platform (appharbor in my case, older version of F#)
module Api =
type UserPass = {
user: string;
pass : string }
type Login = {
id : int
[<Json>] data : UserPass }
type EndPoint =
| [<EndPoint "POST /login">] Login of Login ...
let dispatch context = function
| Login { data = userpass } -> ...
type EndPoint =
| [<EndPoint "/api">] Api of Api.EndPoint ..
Application.MultiPage (fun ctx -> function
| Api api -> Api.dispatch ctx api
... )
Is there an acceptable way to get a textual body content of the http request?
And it works fine if I use record type with just one field
type UserPass = {
user: string;
///pass : string
}
This is quite strange, because using your code above and querying POST /api/login/123 with { "pass": "zxczxc", "user": "sdf" } as the body works here. I don't see what difference could make it fail on your side. Are you using the latest WebSharper?
To get the whole request body you can do:
use tr = new System.IO.StreamReader(ctx.Request.Body)
let input = tr.ReadToEnd()
Of course, since it's inside the handler, it will only be run if the request was matched.
Btw, I think you should be able to use a more recent version of F# on AppHarbor by grabbing the compiler from NuGet instead of using the preinstalled one.
Well, I recheck all about what you mentioned. Many thanks for help!
I don't see what difference could make it fail on your side.
I have absolutely no clue about this
Are you using the latest WebSharper?
yes, of course
Hello! Can you give a guess why this class does not serialize in JSON [NoEncodingException: No JSON encoding for LayoutObjects.LineDashMode]?
[JavaScript, Serializable]
public struct LineDashMode
{
public static class Mode
{
public const int Solid = 0;
public const int Empty = 1;
public const int Pattern = 2;
}
public readonly int mode;
public readonly double[] spans;
//public readonly int bitCount;
private LineDashMode(int mode, double[] spans)
{
this.mode = mode;
this.spans = spans;
}
public LineDashMode(double[] spans)
{
this.mode = Mode.Pattern;
this.spans = spans;
}
public static readonly LineDashMode Solid = new LineDashMode(Mode.Solid, null);
public static readonly LineDashMode Empty = new LineDashMode(Mode.Empty, null);
public bool isPattern
{
get { return mode == Mode.Pattern; }
}
public bool isSolid
{
get { return mode == Mode.Solid; }
}
public bool isEmpty
{
get { return mode == Mode.Empty; }
}
}
Do the static fields interfere somehow?
@V0d01ey Hi, sorry, error reporting should be improved here. I think what happens here is that WebSharper's serializer currently only looks for a parameterless constructor to create the object, then set the fields. (https://github.com/dotnet-websharper/core/blob/master/src/compiler/WebSharper.Core/Json.fs#L1245)
For now, just add a public LineDashMode() { }.
@Jand42 , does it mean that C# structs won't be serializable?