wcf 反序列化:我们可以推断 javascript 类型吗?
我正在使用 JQuery 和 ajax 调用 asp.net web 服务,使用 json 传输数据。 我正在创建将被 json 字符串化的 javascript 对象。我需要我的 webmethod 来检索这些特定的对象类型,但我的参数类型是基类,这些对象继承自我的基类,如下所示 :
[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 服务器能够反序列化我的数组中的正确类型。 但是一旦在我的 webmethod 中,“formobjects”都是 FormElement 类型,即使使用 serviceknowntype 属性,我也无法获取它们的真实类型。是因为 javascript 不是强类型的,所以我无法检索具体类型吗?因为字符串化的 json 不会给出具体类型? 我尝试过
textObject.prototype = new textObject(typedquestion);
objectarray.push(textObject.prototype);
,json给出了类似的东西:
{"formobjects":{"textObject": {"question":"test"}}}
但是服务器端还是老样子,我只在我的webmethod中获得FormElement类型,并且无法转换。
也许我想做的事是不可能的.. 无论如何谢谢你!
I'm calling an asp.net webservice with JQuery and ajax, transfering data with json.
I'm creating javascript objects that will be json stringified. I need my webmethod to retrieve these particular object types but my parameter type is a base class and those objects inherit from my base class like this :
[DataContract]
[KnownType(typeof(TextareaObject))]
[KnownType(typeof(TextObject))]
public class FormElement
{
public FormElement()
{}
}
and :
[DataContract(Name = "textObject")]
public class TextObject : FormElement
{
[DataMember]
public string question { get; set; }
public TextObject(string question)
{
this.question = question;
}
}
and my webmethod :
[WebInvoke(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[OperationContract]
[ServiceKnownType(typeof(TextObject))]
[ServiceKnownType(typeof(TextareaObject))]
public void SaveForm(List<FormElement> formobjects)
{
...
}
And here's the way I'm creating javascript objects (I copy only relevant samples of my code) :
//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
}
});
And I want asp.net server to be able to deserialize the correct type in my array.
But once in my webmethod, "formobjects" are all of type FormElement, I can't get their real type even with serviceknowntype attributes. Is is because javascript isn't strongly typed that I can't retrieve the concrete types ? because the stringified json won't give the concrete type?
I tried with
textObject.prototype = new textObject(typedquestion);
objectarray.push(textObject.prototype);
and the json gives something like :
{"formobjects":{"textObject": {"question":"test"}}}
But server side same old same old, I only get FormElement type in my webmethod and I can't cast.
maybe what I wanna do is not possible..
thank you anyway !!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
没有类型信息,因此 WCF 序列化程序不知道要反序列化为哪种类型。
如果有一种方法可以根据 json 的格式来解决这个问题,您可以编写自己的序列化程序来处理此方法的反序列化 - 请参阅 这篇 MSDN 博客文章了解如何为 WCF 编写自定义序列化程序。
There is no type information, so the WCF serializers do not know which type to deserialize to.
If there is a way to figure this out based on the format of your json, you could write your own serializer to handle deserialization for this method - see this MSDN blog post for how to write a custom serializer for WCF.
如果您使用的是 c# 4,我认为您可以使用新类型
dynamic
:http://msdn.microsoft.com/en-us/library/dd264736.aspx
If you're on c# 4, I think this is a case where you can use the new type
dynamic
:http://msdn.microsoft.com/en-us/library/dd264736.aspx
好吧,我找到了答案。正如 rich.okelly 所说,弱类型语言(即 javascript)不会发送类型信息,因为 javascript 类不是像 .net 中那样的真正类。但微软预计,你需要使用他们所谓的“类型提示”,这意味着你将“__type”属性添加到你的javascript对象中,并在第一个位置像这样:
或者甚至将它添加到类本身中,这样你就不会' t add 每次都进行设置:
在问题后添加 __type 不起作用。另外,即使没有命名空间,您也需要在其后面添加“:#”。架构如下:“datacontractname:#datacontractnamespace”。
我发现它以编程方式在我的 TextObject 上创建序列化器,以便我可以找到所需的格式。然后我的 webmethod 中收到的 formelement 是 TextObject 类型!工作完成了!
谢谢大家!
well I found my answer. Like rich.okelly said, there is no type information sent with weakly-typed language that is javascript, because javascript classes aren't real classes like in .net. But Microsoft anticipated that, you need to use what they call "type hints", it means you add "__type" property to your javascript objects, and in the first position like so :
or even add it to the class itself so you don't add to set it each time:
adding __type after question won't work. Plus, even if there is no namespace you need to add ":#" after it. the schema follows : "datacontractname:#datacontractnamespace".
I found it programatically creating serializer on my TextObject so that I can find the needed format. Then my formelement received in my webmethod is type of TextObject ! job done !
thank you all !