Put / Post json doesn't work with ODataController if model has Int64

I have this data object with an Int64 column:

[TableAttribute(Name="dbo.vw_RelationLineOfBusiness")]
[DataServiceKey("ProviderRelationLobId")] 
public partial class RelationLineOfBusiness
{

    #region Column Mappings
    private System.Guid _Lineofbusiness;
    private System.String _ContractNumber;
    private System.Nullable<System.Int32> _ProviderType;
    private System.String _InsuredProviderType;
    private System.Guid _ProviderRelationLobId;
    private System.String _LineOfBusinessDesc;
    private System.String _CultureCode;
    private System.String _ContractDesc;
    private System.Nullable<System.Guid> _ProviderRelationKey;
    private System.String _ProviderRelationNbr;
    **private System.Int64 _AssignedNbr;**

      

When I post / move an object through my OData controller using HttpClient and NewtsonSoft:

partial class RelationLineOfBusinessController: ODataController {

public HttpResponseMessage PutRelationLineOfBusiness ([FromODataUri] System.Guid key, Invidasys.VidaPro.Model.RelationLineOfBusiness entity)

entity object is null and error in my state model:

"Unable to convert primitive value to expected type 'Edm.Int64". See inner exception for details.

I noticed when I am on my object using the following url:

Invidasys.Rest.Service / VidaPro / RelationLineOfBusiness (guid'c6824edc-23b4-4f76-a777-108d482c0fee ')

my json looks like this: I noticed that AssignedNbr is treated as a string.

{"Odata.metadata": "Invidasys.Rest.Service/VIDAPro/$metadata#RelationLineOfBusiness/@Element", "Lineofbusiness": "ba129c95-c5bb-4e40-993e-c28ca86fffe4", "ContractNumber": null, "ProviderTypepe : null, "InsuredProviderType": "PCP", "ProviderRelationLobId": "c6824edc-23b4-4f76-a777-108d482c0fee", "LineOfBusinessDesc": "MEDICADE", "CultureCode": "EN-US", "ContractDesc": null , "ProviderRelationKey": "a2d3b61f-3d76-46f4-9887-f2b0c8966914", "ProviderRelationNbr": "4565454645", "AssignedNbr": "1000000045" , "Ispar": true, "ProviderTypeDescPescider": "null," InsyuredDescider"Primary care physician", "StartDate": "2012-01-01T00: 00: 00", "EndDate": "2014-01-01T00: 00: 00", "Creation date": "2014-06-13T10: 59: 33,567 "," CreatedBy ":" Michael "," update ":" 2014-06-13T10: 59: 33,567 "," UpdatedBy ":" Michael "}

When I do a PUT with httpclient, the JSON appears in my calming services like this, and the json for the AssignedNbr column is not in quotes, which causes the rest of the services to be unable to build the JSON back to the object. I played around with JSON and put AssignedNbr in quotes and the request went through correctly.

{ "AssignedNbr": 1000000045 , "ContractDesc": null, "ContractNumber": null, "Creation date": "/ Date (1402682373567-0700) /", "CreatedBy": "Michael", "CultureCode": "EN- US "," EndDate ":" / Date (1388559600000-0700) / "," InsuredProviderType ":" PCP "," InsuredProviderTypeDesc ":" Primary care physician "," Evap ": true," LineOfBusinessDesc ":" MEDICAID ", "Lineofbusiness": "ba129c95-c5bb-4e40-993e-c28ca86fffe4", "ProviderRelationKey": "a2d3b61f-3d76-46f4-9887-f2b0c8966914", "ProviderRelationLobId": "c6824fed8d" ab4bration ":" 4565454645 ","ProviderType": null, "ProviderTypeDesc": null, "StartDate": "/ Date (1325401200000-0700) /", "update": "/ Date (1408374995760-0700) /", "UpdatedBy": "ED"}

The reason we wanted to expose our business model as reassuring services was to hide any data validation and provide all of our databases in a format that is easy to devise against. I looked at the DataServiceContext to see if it would work, but it uses but uses XML to communicate between the rest of the services and the client. That would work, but the DataServiceContext doesn't provide the messaging layer that HttpRequestMessage / HttpResponseMessage gives me error / missing information with their message.

We plan to support multiple devices from our service platform, but this requires me to be able to use NewtonSoft Json as well as Microsoft DataContractJsonSerializer if needed.

My question for a restful service point is is there a way that I can configure / encode restful services for AssignedNbr, both in JSON and without quotes.

Or in terms of JSON, this is the way I can construct JSON without getting caught up in the serializing business and don't want our clients to deal with custom serializers if they want to write their own apps against our calm services.

Any suggestions?

Thank.

+3


source to share


2 answers


I think you can upgrade to Web API 2.2 for OData V4. Here's the info:

Announcing the release of ASP.NET MVC 5.2, Web API 2.2, and Web Pages 3.2

OData V4 Spec says:

3.2 Controlling the representation of numbers

The IEEE754Compatible = true format parameter specifies that the service MUST serialize Edm.Int64 and Edm.Decimal numbers (including odata.count if required) as strings. Unless specified or specified as IEEE754Compatible = false, all numbers MUST be serialized as JSON numbers.

This allows JavaScript numbers to be supported, which are defined as 64-bit binary IEEE 754 [ ECMAScript ] values (see section 4.3.1.9), causing integers to lose precision beyond the last 15 digits and decimal places to lose precision due to transition from base 10 to base 2. OData JSON that format Edm.Int64 and Edm.Decimal values ​​as strings MUST specify this format parameter in the media type returned in the Content-Type header.



So for a payload like:

@"{ 
    ""Lineofbusiness"": ""ba129c95-c5bb-4e40-993e-c28ca86fffe4"",
    ""AssignedNbr"": ""1000000045""
  }";

      

you have to install:

request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;IEEE754Compatible=true");

      

Otherwise, you shouldn't.

+4


source


Sam Xu is exactly right and should be flagged as the answer.

However, I wanted to add what you need to do to add this to the pipeline.

First, you can set this global, by route, etc. You can find this information here: http://www.asp.net/web-api/overview/advanced/http-message-handlers

Below you will find an example that will work.



public static void Configuration(IAppBuilder builder)
    {
        HttpConfiguration config = new HttpConfiguration();       

        config.MessageHandlers.Add(new MethodOverrideHandler());
    }

public class MethodOverrideHandler : DelegatingHandler
{       
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;IEEE754Compatible=true");

        return base.SendAsync(request, cancellationToken);
    }
}

      

Also, try changing the type you send to the web api instead of the number

Also check the type of decimal you are sending. If he is dialing a line, you can change it to enter the number. For my service, this change no longer throws an error.

//Gnuget Package Manager Install-Package numeral  

if (typeof newValue === 'string') 
{
newValue = numeral().unformat(newValue);
}

  odatajs.oData.request(
             {
                 requestUri: xxx,
                 method: "PATCH",
                 data: { PriceNull: newValue }
             }

      

+2


source







All Articles