WCF не десериализует JSON - параметры в веб-сервисе равны нулю - PullRequest
3 голосов
/ 17 июня 2011

У меня те же проблемы, что и в этом вопросе: WCF не десериализует ввод JSON

Я в растерянности и отчаянно нуждаюсь в решении. Я искал сеть для ответов, но я нашел только этот вопрос, который соответствует моей точной проблеме. Мой параметр datacontract также ничто, когда служба запускается.

Я попробовал пункты ответа в приведенном выше вопросе, но они не дают мне никаких подсказок (веб-служба работает нормально - я не получаю никаких исключений - и я не могу видеть, что делает десериализатор - или не делать, как может быть).

Я использую POST из-за размера вложенного JSON.

Может, какой-нибудь волшебник WCF или оригинальный постер этого вопроса, пожалуйста, просветите меня?

Если потребуется более подробная информация, я предоставлю ее по запросу. Моя проблема очень похожа на эту, и я надеялся, что ОП сможет передать, как он решил эту проблему.

Обновлено

Фрагменты кода - я нахожусь под NDA, поэтому не могу публиковать подробности.

"In-Page JS":

var settings = {
        a: $("#a").val(),
        b: $("#b").val(),
        c: $("#c").val(),
        d: $("#d").val(),
        e: $("#e").val(),
        f: $("#f").prop("checked").toString(),
        g: $("#g").prop("checked").toString()
    };

    var data= {
        a: [1011,1012,1013],
        b: JSON.stringify(settings),
        c: "01/01/2011 23:59:59"
    };

Library.Services.Post("path/to/service/Service.svc/SaveSettings", data, true, function (result) {

        if (result.Succeeded) {
            ShowSuccess("Success.");
        }
        else {
            ShowError("Failure.");
        }

    });

"Library.Services.Post":

Post: function (serviceUrl, data, async, successHandler, errorHandler) {
        var continueOperation = true;

        if (!data) {
            data = "{}";
        }

        try {
            var obj = $.parseJSON(data);
            obj = null;
        }
        catch (err) {
            continueOperation = false;
            JS.ShowError("Data attribute is not a valid JSON object");
        }

        if (typeof (data) !== "string") {
            data = JSON.stringify(data);
        }

        if (continueOperation) {
            Library.Services._ajax("POST", serviceUrl, data, async, successHandler, errorHandler);
        }

        continueOperation = null;
    }

"Library.Services._ajax":

_ajax: function (method, serviceUrl, data, async, successHandler, errorHandler) {

        if (!typeof (successHandler) === "function") {
            continueOperation = false;
            ShowError("Success handler must be a function");
        }

        try {
            $.ajax({
                async: async,
                cache: false, // don't cache results
                type: method,
                url: Library.Services.baseUrl + serviceUrl,
                contentType: "application/json; charset=utf-8",
                data: data,
                dataType: "json",
                processData: false, // data processing is done by ourselves beforehand
                success: function (data, statusText, request) {

                    if (data != null) {
                        if (data.d && data.d.__type) {
                            data = data.d;
                        }
                        else {
                            // Wrapped message: return first property
                            $.each(data, function (name, value) {
                                data = value;
                                return false;
                            });

                        }
                    }

                    successHandler(data, statusText, request);

                },
                error: function (request, statusText, error) {
                    //debugger;    
                    var res = request.responseText;

                    if (request.status != 200) {
                        if (!request.isResolved()) {
                            ShowError(request.status + " " + request.statusText);
                        }
                        else {
                            ShowError("Request could not be resolved.");
                        }
                    }
                    else {
                        ShowError("Unknown error status.");
                    }

                    if (typeof (errorHandler) === "function") {
                        errorHandler();
                    }

                }
            });
        }
        catch (err) {
            ShowError("AJAX call failed");
        }
    }

"Service.svc":

<DataContract()>
Public Class SaveSettingsContract
    <DataMember(Order:=1)>
    Public a() As String

    <DataMember(Order:=2)>
    Public b()() As String

    <DataMember(Order:=3)>
    Public c As String

End Class

<OperationContract()>
<WebInvoke(BodyStyle:=WebMessageBodyStyle.Wrapped,
        RequestFormat:=WebMessageFormat.Json,
        ResponseFormat:=WebMessageFormat.Json)>
Public Function SaveSettings(ByVal settings as SaveSettingsContract) As WebServiceResults.BaseResult

   ' At this point in debugging, settings is Nothing


End Function

Ответы [ 2 ]

2 голосов
/ 17 июня 2011

Трудно сказать, не зная всего вашего кода, но, возможно, вам поможет диагностика вашей проблемы.

Создайте небольшое тестовое приложение (достаточно консоли), которое будет использовать DataContractJsonSerializer напрямую.Если у вас есть этот вспомогательный инструмент, вы можете попытаться десериализовать захваченное сообщение JSON в ваши контракты данных (используйте Fiddler для захвата JSON) или вы можете попытаться создать ожидаемый контракт данных и сериализовать его, а также сравнить сериализованное и входящее сообщение (они должны совпадать)..

1 голос
/ 15 марта 2012

Мне кажется, я нашел ответ на этот вопрос.

Я думаю, что причина, по которой параметр был нулевым, заключалась в следующем:

var data= {
    a: [1011,1012,1013],
    b: JSON.stringify(settings),
    c: "01/01/2011 23:59:59"
};

должно быть так:

var data = {
    settings: {
        a: [1011,1012,1013],
        b: JSON.stringify(settings),
        c: "01/01/2011 23:59:59"
    }
}

Требуемые данные нужно было обернуть в переменную settings, которая соответствует имени параметра метода SaveSettings. Служба не помещает автоматически отправляемые вами данные в параметр settings.

Это звучит ослепительно очевидно, теперь я оглядываюсь назад, но по какой-то причине я упустил это, когда создавал сервис изначально.

Редактировать: Я думаю, что я пропустил это, потому что со старыми сервисами asmx вы могли передавать данные в том же порядке, что и параметры, и сервис автоматически заполнял параметры правильными значениями. В WCF, однако, это не так, и вы должны явно указать их.

...