ASP.NET ScriptService deserialization problem with derived types












7















I have a ScriptService web method (.NET 3.5) which takes a single parameter of an abstract base type:



[WebMethod(EnableSession=true)]
[ScriptMethod()]
public bool Test(Item item) { ... }


And:



namespace Namespace {
public abstract class Item
{
public int id;
}

public class Group : Item
{
public Item items;
}

public class Instance : Item
{
public string whatever;
}
}


Usually, when the method is called, item will be a Group which contains Instance and/or Group objects. I'm calling this service from jQuery; I'm not using the Microsoft client-side framework. Calls to other methods work fine.



The problem: When I make the call, an exception is thrown before my method is even invoked. For example, if my call is:



POST /WebService.asmx/Test HTTP/1.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/javascript, */*

{"item":{"id":0,"__type":"Namespace.Group","items":}}


...I get an InvalidOperationException:



{"Message":"Operation is not valid due to the current state of the object.","StackTrace":"   at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)rn   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)rn   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)rn   at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.InvalidOperationException"}


If I drop the __type member of the JSON object or change it to Namespace.Item (and remove the abstract modifier from Item), the exception goes away, but the resulting deserialized object is obviously kinda useless.



What am I missing?










share|improve this question























  • I got an error just like this but my was problem completely different. I converted a WCF service into an ASMX service. Each one uses a different format for the __type property. Updating __type to use ASMX's format completely resolved the issue for me.

    – sparebytes
    Jul 25 '12 at 20:22
















7















I have a ScriptService web method (.NET 3.5) which takes a single parameter of an abstract base type:



[WebMethod(EnableSession=true)]
[ScriptMethod()]
public bool Test(Item item) { ... }


And:



namespace Namespace {
public abstract class Item
{
public int id;
}

public class Group : Item
{
public Item items;
}

public class Instance : Item
{
public string whatever;
}
}


Usually, when the method is called, item will be a Group which contains Instance and/or Group objects. I'm calling this service from jQuery; I'm not using the Microsoft client-side framework. Calls to other methods work fine.



The problem: When I make the call, an exception is thrown before my method is even invoked. For example, if my call is:



POST /WebService.asmx/Test HTTP/1.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/javascript, */*

{"item":{"id":0,"__type":"Namespace.Group","items":}}


...I get an InvalidOperationException:



{"Message":"Operation is not valid due to the current state of the object.","StackTrace":"   at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)rn   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)rn   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)rn   at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.InvalidOperationException"}


If I drop the __type member of the JSON object or change it to Namespace.Item (and remove the abstract modifier from Item), the exception goes away, but the resulting deserialized object is obviously kinda useless.



What am I missing?










share|improve this question























  • I got an error just like this but my was problem completely different. I converted a WCF service into an ASMX service. Each one uses a different format for the __type property. Updating __type to use ASMX's format completely resolved the issue for me.

    – sparebytes
    Jul 25 '12 at 20:22














7












7








7


2






I have a ScriptService web method (.NET 3.5) which takes a single parameter of an abstract base type:



[WebMethod(EnableSession=true)]
[ScriptMethod()]
public bool Test(Item item) { ... }


And:



namespace Namespace {
public abstract class Item
{
public int id;
}

public class Group : Item
{
public Item items;
}

public class Instance : Item
{
public string whatever;
}
}


Usually, when the method is called, item will be a Group which contains Instance and/or Group objects. I'm calling this service from jQuery; I'm not using the Microsoft client-side framework. Calls to other methods work fine.



The problem: When I make the call, an exception is thrown before my method is even invoked. For example, if my call is:



POST /WebService.asmx/Test HTTP/1.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/javascript, */*

{"item":{"id":0,"__type":"Namespace.Group","items":}}


...I get an InvalidOperationException:



{"Message":"Operation is not valid due to the current state of the object.","StackTrace":"   at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)rn   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)rn   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)rn   at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.InvalidOperationException"}


If I drop the __type member of the JSON object or change it to Namespace.Item (and remove the abstract modifier from Item), the exception goes away, but the resulting deserialized object is obviously kinda useless.



What am I missing?










share|improve this question














I have a ScriptService web method (.NET 3.5) which takes a single parameter of an abstract base type:



[WebMethod(EnableSession=true)]
[ScriptMethod()]
public bool Test(Item item) { ... }


And:



namespace Namespace {
public abstract class Item
{
public int id;
}

public class Group : Item
{
public Item items;
}

public class Instance : Item
{
public string whatever;
}
}


Usually, when the method is called, item will be a Group which contains Instance and/or Group objects. I'm calling this service from jQuery; I'm not using the Microsoft client-side framework. Calls to other methods work fine.



The problem: When I make the call, an exception is thrown before my method is even invoked. For example, if my call is:



POST /WebService.asmx/Test HTTP/1.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/javascript, */*

{"item":{"id":0,"__type":"Namespace.Group","items":}}


...I get an InvalidOperationException:



{"Message":"Operation is not valid due to the current state of the object.","StackTrace":"   at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)rn   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)rn   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)rn   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)rn   at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.InvalidOperationException"}


If I drop the __type member of the JSON object or change it to Namespace.Item (and remove the abstract modifier from Item), the exception goes away, but the resulting deserialized object is obviously kinda useless.



What am I missing?







c# javascript ajax json scriptservice






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Sep 29 '10 at 5:51









josh3736josh3736

106k20179231




106k20179231













  • I got an error just like this but my was problem completely different. I converted a WCF service into an ASMX service. Each one uses a different format for the __type property. Updating __type to use ASMX's format completely resolved the issue for me.

    – sparebytes
    Jul 25 '12 at 20:22



















  • I got an error just like this but my was problem completely different. I converted a WCF service into an ASMX service. Each one uses a different format for the __type property. Updating __type to use ASMX's format completely resolved the issue for me.

    – sparebytes
    Jul 25 '12 at 20:22

















I got an error just like this but my was problem completely different. I converted a WCF service into an ASMX service. Each one uses a different format for the __type property. Updating __type to use ASMX's format completely resolved the issue for me.

– sparebytes
Jul 25 '12 at 20:22





I got an error just like this but my was problem completely different. I converted a WCF service into an ASMX service. Each one uses a different format for the __type property. Updating __type to use ASMX's format completely resolved the issue for me.

– sparebytes
Jul 25 '12 at 20:22












2 Answers
2






active

oldest

votes


















15














Ah ha! Clicking around the related links on the right side of this question, I found an answer that helped me solve this problem.



The GenerateScriptType attribute must be applied to the web service class:



[WebService( ... )]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
[GenerateScriptType(typeof(Group))]
[GenerateScriptType(typeof(Instance))]
public class WebService : System.Web.Services.WebService
{
[WebMethod(EnableSession=true)]
[ScriptMethod()]
public bool Test(Item item) { ... }
}


Without these attributes, the deserializer doesn't know about my derived types.






share|improve this answer

































    0














    I could solve this using Newtonsofts JsonConvert as below.



    [System.Web.Services.WebMethod]      
    public static void MyAjaxCallingMethod(object inputs)
    {
    string stingDataFromAjaxCall = JsonConvert.SerializeObject(inputs);
    MyObject myObj = JsonConvert.DeserializeObject<MyObject>(stingDataFromAjaxCall);
    ....}





    share|improve this answer


























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3819071%2fasp-net-scriptservice-deserialization-problem-with-derived-types%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      15














      Ah ha! Clicking around the related links on the right side of this question, I found an answer that helped me solve this problem.



      The GenerateScriptType attribute must be applied to the web service class:



      [WebService( ... )]
      [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
      [ScriptService]
      [GenerateScriptType(typeof(Group))]
      [GenerateScriptType(typeof(Instance))]
      public class WebService : System.Web.Services.WebService
      {
      [WebMethod(EnableSession=true)]
      [ScriptMethod()]
      public bool Test(Item item) { ... }
      }


      Without these attributes, the deserializer doesn't know about my derived types.






      share|improve this answer






























        15














        Ah ha! Clicking around the related links on the right side of this question, I found an answer that helped me solve this problem.



        The GenerateScriptType attribute must be applied to the web service class:



        [WebService( ... )]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [ScriptService]
        [GenerateScriptType(typeof(Group))]
        [GenerateScriptType(typeof(Instance))]
        public class WebService : System.Web.Services.WebService
        {
        [WebMethod(EnableSession=true)]
        [ScriptMethod()]
        public bool Test(Item item) { ... }
        }


        Without these attributes, the deserializer doesn't know about my derived types.






        share|improve this answer




























          15












          15








          15







          Ah ha! Clicking around the related links on the right side of this question, I found an answer that helped me solve this problem.



          The GenerateScriptType attribute must be applied to the web service class:



          [WebService( ... )]
          [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
          [ScriptService]
          [GenerateScriptType(typeof(Group))]
          [GenerateScriptType(typeof(Instance))]
          public class WebService : System.Web.Services.WebService
          {
          [WebMethod(EnableSession=true)]
          [ScriptMethod()]
          public bool Test(Item item) { ... }
          }


          Without these attributes, the deserializer doesn't know about my derived types.






          share|improve this answer















          Ah ha! Clicking around the related links on the right side of this question, I found an answer that helped me solve this problem.



          The GenerateScriptType attribute must be applied to the web service class:



          [WebService( ... )]
          [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
          [ScriptService]
          [GenerateScriptType(typeof(Group))]
          [GenerateScriptType(typeof(Instance))]
          public class WebService : System.Web.Services.WebService
          {
          [WebMethod(EnableSession=true)]
          [ScriptMethod()]
          public bool Test(Item item) { ... }
          }


          Without these attributes, the deserializer doesn't know about my derived types.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 23 '17 at 12:14









          Community

          11




          11










          answered Sep 29 '10 at 6:20









          josh3736josh3736

          106k20179231




          106k20179231

























              0














              I could solve this using Newtonsofts JsonConvert as below.



              [System.Web.Services.WebMethod]      
              public static void MyAjaxCallingMethod(object inputs)
              {
              string stingDataFromAjaxCall = JsonConvert.SerializeObject(inputs);
              MyObject myObj = JsonConvert.DeserializeObject<MyObject>(stingDataFromAjaxCall);
              ....}





              share|improve this answer






























                0














                I could solve this using Newtonsofts JsonConvert as below.



                [System.Web.Services.WebMethod]      
                public static void MyAjaxCallingMethod(object inputs)
                {
                string stingDataFromAjaxCall = JsonConvert.SerializeObject(inputs);
                MyObject myObj = JsonConvert.DeserializeObject<MyObject>(stingDataFromAjaxCall);
                ....}





                share|improve this answer




























                  0












                  0








                  0







                  I could solve this using Newtonsofts JsonConvert as below.



                  [System.Web.Services.WebMethod]      
                  public static void MyAjaxCallingMethod(object inputs)
                  {
                  string stingDataFromAjaxCall = JsonConvert.SerializeObject(inputs);
                  MyObject myObj = JsonConvert.DeserializeObject<MyObject>(stingDataFromAjaxCall);
                  ....}





                  share|improve this answer















                  I could solve this using Newtonsofts JsonConvert as below.



                  [System.Web.Services.WebMethod]      
                  public static void MyAjaxCallingMethod(object inputs)
                  {
                  string stingDataFromAjaxCall = JsonConvert.SerializeObject(inputs);
                  MyObject myObj = JsonConvert.DeserializeObject<MyObject>(stingDataFromAjaxCall);
                  ....}






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 23 '18 at 12:59









                  Suraj Rao

                  23.9k85973




                  23.9k85973










                  answered Nov 23 '18 at 12:44









                  Maithree DuggiralaMaithree Duggirala

                  1




                  1






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3819071%2fasp-net-scriptservice-deserialization-problem-with-derived-types%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      Xamarin.form Move up view when keyboard appear

                      Post-Redirect-Get with Spring WebFlux and Thymeleaf

                      Anylogic : not able to use stopDelay()