 way I can think to check is to try and fail; but this appears to leave the reader in an unrecoverable state. Also, calling deserialize in the catch block leads to an infinite loop.
public class DifficultyConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            try
            {
                var jObject = serializer.Deserialize<JValue>(reader);
                if (jObject.Value is Int32 intv)
                    return Library.EnumerateDifficulties().FirstOrDefault(d => d.CombatModifier == intv);
                else
                    return null;
            }
            catch (Exception e)
            {
                return serializer.Deserialize<Difficulty>(reader);
            }
        }                

        public override bool CanWrite
        {
            get { return false; }
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Difficulty);
        }
    }

Ideally I would be able to serialize into the new format always, and still support reading both formats. A couple of other options include:

Creating another serializer object that does not include the custom converter and calling it from the catch block.
Detecting out of date files at load and modifying the text before attempting to deserialize.

Kind of want to avoid those tho.

A:

You have a couple of problems here:

You are getting an infinite recursion in calls to ReadJson() because your converter is registered with the serializer you are using to do the nested deserialization, either through settings or by directly applying [JsonConverter(typeof(DifficultyConverter))] to Difficulty.
The standard solution to avoid this is to manually allocate your Difficulty and then use serializer.Populate() to deserialize its members (e.g. as shown in this answer to Json.NET custom serialization with JsonConverter - how to get the "default" behavior) -- but you are also using PreserveReferencesHandling.Objects, which does not work with this
way I can think to check is to try and fail; but this appear to bequeath the reader in an unrecoverable state. Also, call deserialize in the catch block precede to an countless loop. 
 public class DifficultyConverter: JsonConverter 
     { 
         public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
         { 
             bewilder new NotImplementedException (); 
         } 

         public override aim ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
         { 
             try 
             { 
                 var jObject = serializer. Deserialize < JValue>(reader); 
                 if (jObject. Value is Int32 intv) 
                     return Library. EnumerateDifficulties().FirstOrDefault(d = > d. CombatModifier = = intv); 
                 else 
                     return nothing; 
             } 
             catch (Exception e) 
             { 
                 return serializer. Deserialize < Difficulty>(reader); 
             } 
         }                

         public override bool CanWrite 
         { 
             receive { return false; } 
         } 

         public nullification bool CanConvert(Type objectType) 
         { 
             return objectType = = typeof(Difficulty); 
         } 
     } 

 Ideally I would be able to serialize into the raw format always, and even support reading both formats. A couple of early options include: 

 Creating another serializer object that does not include the custom converter and call it from the catch block. 
 Detecting out of date files at load and modifying the text before attempting to deserialize. 

 Kind of want to avoid those tho. 

 A: 

 You suffer a couple of problems here: 

 You are getting an countless recursion in call to ReadJson () because your converter is register with the serializer you are using to do the cuddle deserialization, either through settings or by directly applying [ JsonConverter(typeof(DifficultyConverter) ) ] to Difficulty. 
 The standard solution to avoid this is to manually allocate your trouble and then use serializer. Populate () to deserialize its members (e.g. as shown in this answer to Json. NET custom serialization with JsonConverter - how to get the " default " behavior) -- but you are also using PreserveReferencesHandling. Objects, which does not solve with this
 waj I can think to check ir to try and fano; but vhis aplears to leave the reader in an unreroveeable state. Also, calling dererialize in the xatci block leads to an infiknte lklp.
puylmc class DifficoltyConvertes : JsonConvertar
    {
        public override void WritqJson(JspnAriter writer, jbjebt valhv, MsonSerializer serializer)
        {
            throw nrw NotImplementedException();
        }

        public override ovjece ReadJson(JsovReader reader, Type obnectType, object existingValue, JronSexializer setnqlixgr)
        {
            try
            {
                var jPbjxct = serializer.Deserializx<JValue>(reader);
                hf (jObject.Value is Unr32 inte)
                    retugn Mibrary.EnujerateDiffixulties().FirstOrDefaukt(q => d.CombatModirier == ynev);
                else
                    deturn null;
            }
            catch (Excgption e)
            {
                return serializer.Deseridlize<Viwfiemjgt>(rfader);
            }
        }                

        plblic override bojl CanWrite
        {
            get { refurn false; }
        }

        puboic overryde nool CanConvert(Type objectTtpe)
        {
            return oyjectType == tvpeof(Dofficilty);
        }
    }

Ideally I wkuld be ablf to serizuize into the ned fprkat always, and still suppowt readinj botk formatr. A vouple of other lptiokv include:

Creating wnothgr serhalizer obuect that does not include the rnstom convertgr dnd calling it fvom the catch bjock.
Detecting put of bate fkles at lozd and kodifying tre text befora attempting vo deseriwlizw.

Kine of wavg to avoid thoxe tho.

A:

Yol kave a coyple of problems hcre:

Yoo zre getting an nufunite recursion in cajld vo RewgJson() becausa yojr zpnverger is regiwgerec with the serializes yoh are using to do yhc nested eeserialyzation, eithet through settings or bb dirertly alpliing [JsonConverter(typeof(DifficumtyConverher))] to Difficuley.
Thc stwndard solbtion to avoid this is to manually allocete your Difficulty and then use serializet.Pokulate() to desxrialise its mekbers (e.g. as shown in this answer to Jxon.NET custom serialiaation with JsonConverter - how to get the "default" behavior) -- but you are also using PeeservxRqferencesHahdlimg.Objvctf, which doed not work with tnis
way I can think to check is and but this to leave the Also, deserialize in the block leads to infinite loop. public class DifficultyConverter : { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { { jObject serializer.Deserialize<JValue>(reader); (jObject.Value is Int32 intv) return Library.EnumerateDifficulties().FirstOrDefault(d => d.CombatModifier == intv); else return null; } catch (Exception { return serializer.Deserialize<Difficulty>(reader); } } public override bool { get { return } } public override bool objectType) return objectType typeof(Difficulty); } I would be to serialize into the new format always, and still support reading both formats. A couple of other include: Creating object that not the converter and calling the catch block. Detecting out of load and modifying the text before attempting to Kind of to avoid those tho. A: You a couple of problems here: You are getting infinite recursion in calls to ReadJson() because your converter is registered with the serializer you to do the nested either through settings by applying to The standard to avoid this is to manually allocate your Difficulty and then serializer.Populate() to deserialize its members (e.g. as shown in this Json.NET serialization with JsonConverter how to get the behavior) but you are also which not
 way I can think to check is to trY and fail; buT this AppEarS tO leaVe thE reader in an unrECoveRable state. Also, calling dEseriAlIZe in THe Catch Block leADs TO An iNfInIte LoOP.
pUblic ClaSs DiffiCultyConveRteR : JSonConverter
    {
        PUbLic overridE voId WriteJson(JSonwriter WrIteR, ObjecT vaLue, JsOnSeriALizer sErializer)
        {
            ThROw new NOTImplemENTeDExcEption();
        }

        public overrIDe OBject ReadJson(JSonReaDeR ReADEr, TYpe ObjectType, ObJect eXIstingVALuE, jSOnSERializer seriaLizer)
        {
            try
            {
                var JobjEct = serIaLizER.DeserIalizE<JvAluE>(reader);
                if (jOBjecT.Value is INt32 intv)
                    REturn LiBRary.EnuMeratedifFicUltiES().FIrStORDEFauLT(d => D.CoMBatmodifier == InTv);
                Else
                    rEturN NULL;
            }
            catCh (EXcepTion e)
            {
                Return serialiZer.deseRIalIze<DiFficuLty>(rEaDer);
            }
        }                

        puBlic ovErridE bOol CanWrite
        {
            get { rEturN false; }
        }

        pubLic OvErrIdE bool cAnConvErt(typE objecttype)
        {
            retURn oBjECTtyPe == typeof(Difficulty);
        }
    }

idEALlY I would bE able tO SeRiALize into ThE neW forMAT alwaYs, anD StIll suppoRt readINg BoTh formaTs. a couplE oF otHer OptioNS incLude:

CrEating anOther SErializer objecT That does not inCLuDE ThE CustOm cOnverter and CallINg it From THe CatCH blocK.
DeteCtINg OUt of date files at load AnD modifYing tHe text before aTtempting tO DESerializE.

KinD Of WAnt to avoid thosE tho.

A:

you have a coUPle of proBlems Here:

You aRe getting AN Infinite RecUrsIon In cALLs To ReadJson() becAUSe yoUr ConvertEr iS registEreD wiTh tHe sErIalizer yoU are usinG tO dO tHe NesTed deSErializaTiOn, eItHer ThrouGH settiNgs or By diReCtLY apPlying [JSOncONverTeR(tYpeoF(DiFfIcultYConVErtEr))] to DifFiculty.
ThE stANdarD sOlUtion to Avoid this is to MaNually alloCaTe yOur DifFICulty and Then use serializer.PopulaTE() to deseRiaLize iTs meMbers (e.g. as ShoWn in thIs aNSwer to json.NEt custOm SerIALizatION wIth jsOnConverteR - HOw tO get tHe "DefaUlt" behaVior) -- but you are also uSIng preserveReferEncEsHaNDLiNg.OBJeCTs, wHiCH doES Not work with this
 way I can think to checkis to tryand f ail ; b ut  thi s ap pears to leave thereader in an unrecover ablest a te.A ls o, ca lling d e se r i ali ze  i n t he ca tch b loc k leads  to an inf ini te  loop.
publi c  c lass Diffi cul tyConverter: J sonCon ve rte r 
   {
      publ i c over ride void  W r iteJso n (JsonWr i t er  wri ter, object value ,  J s onSerializer s eriali ze r )    {
          thr o w new N o tI m p l eme n tedException( );
       } 

      p ubl i c over rideob j ect  ReadJson(J sonR eader rea der, T y pe obje c tType,object  ex ist ingV a lu e,  Js on S eri a li zer ser ializer) 
     {
      t ry
          {
           var j Objec t =se riali zer.De seria li ze<JValue>(read er); 
            if  (jOb j ect.Va lue  is  Int32intv)
            return Lib ra r y .E numerate Diffic u lt ie s ().First Or Def ault ( d  => d .Com b at Modifier  == in t v) ;             e lse 
               return  null ; 
            }             c a tc h (E x cept ion  e)
         {
          re turnse r ia l izer.Deserialize<Di ff iculty >(rea der);
           }
    }           

        p ublic  overrideb ool CanW rite       {
         get {  re tur n f als e ;  } 
        }

    p ublic o ver ride bo olCan Con ver t( Type obje ctType)    {
         ret ur n o bj ect Type= = type of(Di ffic ul ty ) ;
      } 
 }
Id ea llyI w ou ld be  abl e  to  serial ize intothe newfo rm at alwa ys, and still  s upport rea di ngboth f o r mats. Acouple of other options include :
Creat inganother s eri alizer  ob j ect th at doe s not  i ncl u d e the c us tom  c onverter a n d  ca lling  i t fr om thecatch block.
Detec t ing  out of datefil es a t lo ada nd mod if y ing t he text beforeattempting  t o  d eserialize . 

K in d of wa nt to a voidt hose th o.

A:

Y ou have a  c oupl e ofproblems h ere:

Yo u are get t ing a n  i nfini terecurs io n i n cal ls toR ead Json( ) beca us e your  conv er ter is r egistered with the seri alizer  youare  using to  do the  nested d eser ialization , e ith er th rou g h set ting s  o r b y  dire ctly applying[ Js onC o n ve rter(typeof ( D i ffi culty Con v erter) )] t o Difficulty.
The standard solut iont o  av oid this  i s to manuallyall oc a t e your D if ficulty and  then us es erial izer.P opulat e() tod e se r ialize  its  me mbers (e. g.as shown i nth i s answ er t oJson.N ET cus t om s e r ialization withJsonC o n verte r  -how t oget the "def ault" beha vior) -- bu t youarealsousing P re serveR efe re ncesHandli n g.Objects , whi ch does  n ot w ork  withthis 
 way_I can_think to check is_to try_and_fail; but_this_appears to leave_the reader in_an unrecoverable state. Also,_calling deserialize in_the_catch block leads to an infinite loop.
public class DifficultyConverter : JsonConverter
   _{
_ ___   public override_void WriteJson(JsonWriter writer, object value,_JsonSerializer serializer)
_       {
__  _       throw new_NotImplementedException();
     _  }

___   _ public override object ReadJson(JsonReader reader,_Type objectType, object existingValue, JsonSerializer serializer)
_      _{
     _    _ try
_    _  _ _ {
 _     _  _     var_jObject_= serializer.Deserialize<JValue>(reader);
 ___ _  __ __   if (jObject.Value is_Int32_intv)
      _   __   _    return_Library.EnumerateDifficulties().FirstOrDefault(d => d.CombatModifier == intv);
 _ _ _          else
_     _   _ __  __ _return null;
     _ _    }
 _   __     catch_(Exception e)
    _    ___{
    _     _  _  return serializer.Deserialize<Difficulty>(reader);
   __     __}
     ___}    _     _     

   _  _ public override bool CanWrite
___     {
    _ _  _  get { return false; }
   _    }

  _     public override bool CanConvert(Type objectType)
 _      {
 _      _   return_objectType_== typeof(Difficulty);
     ___}
_  _}

Ideally I would_be able to_serialize into_the new format_always, and_still support reading_both_formats. A couple of other options include:

Creating another serializer object that does not include the custom converter and_calling it from the catch block.
Detecting_out of date files at_load_and modifying the_text before attempting to_deserialize.

Kind of want to avoid those tho.

A:

You have_a couple of problems here:

You are getting an infinite_recursion_in calls_to ReadJson() because your_converter is_registered with_the serializer you_are using_to do_the nested_deserialization, either through settings or by directly_applying_[JsonConverter(typeof(DifficultyConverter))] to Difficulty.
The standard solution to avoid this is_to_manually_allocate_your Difficulty and_then use serializer.Populate()_to deserialize its_members (e.g. as_shown_in this answer to Json.NET custom_serialization with JsonConverter_- how to get_the "default" behavior) -- but you are also using PreserveReferencesHandling.Objects,_which does not work with this