在webmethod中使用json.net序列化程序
我将从我的问题开始:
我有一个webmethod,我通过AJAX / JSON调用. [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] [System.Web.Script.Services.ScriptService] public class MyService : System.Web.Services.WebService { [WebMethod] public string GlobalMethod(Container data) { string result = ""; foreach (var item in data.Items) { result += item.BaseProperty; if (item is FirstDerivedClass) result += ((FirstDerivedClass)item).FirstDerivedProperty; else if (item is SecondDerivedClass) result += ((SecondDerivedClass)item).SecondDerivedProperty; } return result; } } public class Container { public List<BaseClass> Items; } public abstract class BaseClass { public string BaseProperty; } public class FirstDerivedClass : BaseClass { public string FirstDerivedProperty; } public class SecondDerivedClass : BaseClass { public string SecondDerivedProperty; } 这种方法根本无法解决.我将无法使用默认的JavascriptSerializer调用此方法,因为序列化程序无法解析容器将具有的对象类型:它们可以是FirstDerivedClass或SecondDerivedClass类型. 所以,浏览网页寻找我的问题的解决方案,我遇到了Json.NET,其方法JsonConvert.DeserializeObject能够检索使用JsonConvert.SerializeObject序列化的原始对象类型,因为它添加了一个名为“$type”的属性”. 我现在的问题是:如何使用此序列化程序而不是ASMX使用的默认方法制作web方法? [WebMethod] public string GlobalMethod(Container data) 然后我将获得一个完全空的Container对象,因为框架正在进行反序列化工作,并且不知道要实例化哪些项目,并且我无法告诉框架它应该使用Json.NET来完成工作,能够完全反序列化数据. 如果我尝试这种方式修改方法 [WebMethod] public string GlobalMethod(string data) { string result = ""; Container container = JsonConvert.DeserializeObject<Container>(data,new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects }); foreach (var item in container.Items) { ... 然后我会得到另一个服务器错误500,因为“没有为u0027system.string u0027的类型定义无参数构造函数” 好吧,希望我的问题很清楚……我一整天都花在它上面,我似乎找不到解决方案.重新审视我的方法的体系结构,以避免使用派生类是不是一个选项(要注意实际的代码要复杂得多,我只是简化它以达到目的!). 顺便说一句,我将添加调用webmethod的ajax方法以这种方式完成: $.ajax({ type: "POST",url: wsUrl + method,data: JSON.stringify(data),contentType: "application/json; charset=utf-8",dataType: "json",processData: false,success: function(msg) { try{ success(JSON.parse(msg.d)); } finally { } },error: error }); 感谢任何与我分享知识的人! 我想分享一下我是如何解决我的问题的.正如我已经说过的,我用这种方式修改了我的方法: [WebMethod] public string GlobalMethod(string data) { string result = ""; Container container = JsonConvert.DeserializeObject<Container>(data,new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects }); foreach (var item in container.Items) { 最初,我开始收到错误500“没有为u0027system.string u0027类型定义的无参数构造函数” 但最终我发现了原因:从客户端到服务器的json字符串被.NET框架反序列化为包含的对象,该对象不是字符串,而是实际的JSON对象! 所以诀窍是以下,在我的ajax方法中: $.ajax({ type: "POST",**data: JSON.stringify(JSON.stringify(data)),** contentType: "application/json; charset=utf-8",error: error }); 这意味着json对象被封装在另一个字符串中,该字符串将由我的服务器端GlobalMethod(字符串)通过Json.NET手动反序列化. 显然我不会在ajax例程中包含这个双“stringify”,但我会注意将输入中的JSON.stringified数据传递给ajax例程本身! 解决方法
这只是一个黑客,
这只是一个想法,听起来并不优雅但应该有效 我只是好奇 以这种方式更改容器: public class Container { public List<MyUnionBaseClass> Items; } 和定义(伪代码): public class MyUnionBaseClass{ public void MyUnionBaseClass(BaseClass b){ this.setValue(b); }; final public BaseClass getValue(){ if(first!=null) return (BaseClass) first; if(second!=null)return (BaseClass) second; return null; } final public setValue(BaseClass b){ if(b instanceOf firstClass){ first = (FirstClass) b; } if(b instanceOf secondClass){ second = (SecondClass) b; } } private FirstDerivedClass first=null; private SecondDerivedClass second=null; } P.s:这是非常好的,应该加以改进.这有意义吗? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |