десериализация wcf: мы можем вывести тип javascript? - PullRequest
1 голос
/ 19 декабря 2011

Я звоню на веб-сервис asp.net с JQuery и ajax, передавая данные с помощью json.Я создаю объекты javascript, которые будут строковыми.Мне нужен мой веб-метод для извлечения этих конкретных типов объектов, но мой тип параметра является базовым классом, и эти объекты наследуются от моего базового класса следующим образом:

[DataContract]
[KnownType(typeof(TextareaObject))]
[KnownType(typeof(TextObject))]
public class FormElement
{
    public FormElement()
    {}
}

и:

  [DataContract(Name = "textObject")]
public class TextObject : FormElement
{
      [DataMember]
    public string question { get; set; }

    public TextObject(string question)
    {
            this.question = question;
}
}

имой webmethod:

 [WebInvoke(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[OperationContract]
[ServiceKnownType(typeof(TextObject))]
[ServiceKnownType(typeof(TextareaObject))]
public void SaveForm(List<FormElement> formobjects)
{
   ...

}

И вот как я создаю объекты JavaScript (я копирую только соответствующие образцы моего кода):

     //objects to serialize
    function textObject(question) {
        this.question = question;
    }

  //objects to serialize
    function textareaObject(question, rownumber) {
        this.question = question;
        this.rownumber = rownumber;
    }
  var objectarray = new Array();
 if (type == 'text') {
                textobject1 = new textObject(typedquestion);
                objectarray.push(textobject1);
            }
            else if (type == 'textarea') {
                var rownumber = $(elm).children('textarea').attr('rows');
                textareaobject1 = new textareaObject(typedquestion, rownumber);
                objectarray.push(textareaobject1);
            }

  var formobjects = JSON.stringify(objectarray);

 $.ajax({
            type: "POST",
            //Page Name (in which the method should be called) and method name
            url: urlhtml,
            data: '{"formobjects":' + formobjects + '}',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (msg) {
            //dosmth
            }
        });

И я хочу, чтобы сервер asp.netбыть в состоянии десериализовать правильный тип в моем массиве.Но однажды в моем веб-методе все «объекты формы» имеют тип FormElement, я не могу получить их реальный тип даже с атрибутами serviceknowntype.Это потому, что яваскрипт не является строго типизированным, что я не могу получить конкретные типы?потому что строковый JSON не даст конкретный тип?Я попытался с

 textObject.prototype = new textObject(typedquestion);
            objectarray.push(textObject.prototype);

, а json выдает что-то вроде:

{"formobjects":{"textObject": {"question":"test"}}}

Но на стороне сервера все тот же старый, тот же старый, я получаю только тип FormElement в своем веб-методе и не могу привести.

может быть, то, что я хочу сделать, не возможно .. все равно спасибо !!

Ответы [ 3 ]

0 голосов
/ 19 декабря 2011

Если вы находитесь на c # 4, я думаю, что это тот случай, когда вы можете использовать новый тип dynamic:

http://msdn.microsoft.com/en-us/library/dd264736.aspx

0 голосов
/ 19 декабря 2011

ну я нашел свой ответ. Как сказал rich.okelly, нет никакой информации о типах, передаваемой на языке со слабой типизацией, которая является javascript, потому что классы javascript не являются реальными классами, как в .net. Но Microsoft ожидала, что вам нужно использовать то, что они называют «подсказками типов», это означает, что вы добавляете свойство «__type» к своим объектам javascript, и в первой позиции, например, так:

    //objects to serialize
    function textObject(__type, question) {
        this.__type = __type;
        this.question = question;       
    }
(...)
      var textobject1 = new textObject("textObject:#",typedquestion);

или даже добавьте его в сам класс, чтобы вы не добавляли его каждый раз для установки:

    //objects to serialize
    function textObject(question) {
        this.__type = "textObject:#";
        this.question = question;       
    }
(...)
      var textobject1 = new textObject(typedquestion);

добавление __type после вопроса не сработает. Кроме того, даже если пространства имен нет, вам необходимо добавить после него «: #». схема выглядит следующим образом: "datacontractname: #datacontractnamespace". Я обнаружил, что в моем TextObject программно создается сериализатор, чтобы я мог найти нужный формат. Тогда мой элемент, полученный в моем веб-методе, является типом TextObject! Работа выполнена ! спасибо всем!

0 голосов
/ 19 декабря 2011

Информация о типе отсутствует, поэтому сериализаторы WCF не знают, какой тип десериализовать.

Если есть способ выяснить это на основе формата вашего json, вы можете написать свойСериализатор для обработки десериализации для этого метода - см. в этом блоге MSDN о том, как написать собственный сериализатор для WCF.

...