3

シリアル化されたオブジェクトを格納できるように、JsonObject (Data) プロパティを持つ DTO オブジェクトを取得しました。

以下にサービススタックサービスを含めました。

using ServiceStack.ServiceHost;
using ServiceStack.ServiceInterface;
using ServiceStack.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace BuffaloInspection.WebApi.Services
{
    [Route("/_layouts/api/test")]
    public class ItemDTO
    {
        public int ID { get; set; }
        public string Title { get; set; }
        public JsonObject Data { get; set; }
        public string DataStr { get; set; }
    }

    public class TestService : Service
    {
        public ItemDTO POST(ItemDTO request)
        {
            var response = new ItemDTO();

            response.ID = request.ID;
            response.Title = request.Title;

            //Failing
            response.DataStr = request.Data.ToJson();
            response.Data = JsonObject.Parse(response.DataStr);

            return response;
        }
    }
}

上記のサービスを呼び出すために、次の html ページを使用しています。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="SSTest">
<head>
    <title>Service Stack Test</title>
</head>
<body>
    <div ng-controller="TestCtrl">
        <div>ID:<input type="text" name="id" ng-model="item.ID" value="1" /></div>
        <div>Title:<input type="text" name="title" ng-model="item.Title" value="Test" /></div>
        <div>Length:<input type="text" name="length" ng-model="item.Data.Length" value="10" /></div>
        <div>
            <button type="button" value="save" ng-click="save(item)">Save</button>
        </div>
    </div>

    <script type="text/javascript" src="components/jquery/jquery.min.js"></script>
    <script type="text/javascript" src="components/angular/angular.min.js"></script>
    <script type="text/javascript">
        'use strict';
        var app = angular.module('SSTest', []);

        app.controller('TestCtrl', TestCtrl);
        function TestCtrl($scope, $http) {
            $scope.item = {
                ID: 1,
                Title: 'Test "',
                Data: {
                    Length: '10 "'
                }
            };

            $scope.save = function (data) {
                console.log('before:');
                console.log(data);
                $http.post("http://localhost:8001/_layouts/api/test/", data).then(function (result) {
                    console.log('after: ');
                    console.log(result.data);
                    $scope.item = result.data;
                });
            }
        }

    </script>
</body>
</html>

ページを読み込んで保存します。この時点で、クライアント側のオブジェクトは次のようになります。 {"ID":1,"Title":"Test \"","Data":{"Length":"10 \""}}

コードがサーバーコード行に到達すると//Failing、問題はrequest.Dataオブジェクトに既にエスケープされたフィールドが含まれていることです.ToJson()呼び出しはそれを再びエスケープするため、データを取得すると10\\\".

request.Data は、次の情報を持つ JSON オブジェクトです: [0] {[Length, 10 \"]} response.DataStr が含まれるようになりました{"Length":"10 \\\""}

クライアント側に戻ると、戻りオブジェクトには余分なエスケープが含まれています

特殊文字が二重にエスケープされていないことを確認する方法を知っている人はいますか?

4

2 に答える 2

2

まったく同じ状況で、ネストされた JsonObject を使用して動的オブジェクトを取得します (ただし、Json-Schema で制限されています)。

OrmLite を使用するまでは、すべて (シリアライゼーション/デシリアライゼーション) がうまく機能します。TypeSerializer は、格納された dto を逆シリアル化するときに、ネストされた JsonObject の文字列値に引用符を追加します。そのため、Dto がワイヤに逆シリアル化されると、追加の \" が取得されます。

これに対処するために、あなたと同じように、ストア用に別の dto がありますが、代わりに次を使用します。

toStore.DataStr = request.Data.SerializeToString();
response.Data = JsonObject.Parse(toStore.DataStr);

これは、Service Stack 3.9.66 で機能しています。

于 2013-11-07T12:35:25.577 に答える