Friday, March 3, 2017

Reactjs.net 3.0 and the error "Object doesn't support property or method 'assign' on server!" on ASP.net MVC (windows server 2012 r2)

Reactjs.net 3.0 and the error "Object doesn't support property or method 'assign' on server!"on ASP.net MVC 



* If you are too lazy to read the whole text just read the solution


Error

We are using Reactjs.net to generate some of our front-end code and it is a very good tool. On my new project, I've installed Reactjs.net v 3.0.1 on my local system and everything was fine until the time that I had to publish to test server which was Windows server 2012 r2 were I get the error

 
Failed to render mycomponent
Reason: Object doesn't support property or method 'assign'

Stacktrace
 

TypeError: Object doesn't support property or method 'assign' 

at o (Unknown script code:1:14914) 

at w._constructComponentWithoutOwner (Unknown script code:9:12601) 

at w._constructComponent (Unknown script code:9:12465) 

at w.mountComponent (Unknown script code:9:11635) 

at mountComponent (Unknown script code:1:13246) 

at Mixin.mountChildren (Unknown script code:10:9072) 

at h.Mixin._createContentMarkup (Unknown script code:9:25488) 

at h.Mixin.mountComponent (Unknown script code:9:24086) 

at mountComponent (Unknown script code:1:13246) 

at Mixin.mountChildren (Unknown script code:10:9072)


Digging in

So I started to dig in. I've published my code to my local IIS and test it with the same connection string and everything and it was fine, but when I copied the same files to the server I had the error.
With more investigation I found this post here on issues

By default ReactJS.NET will try to use V8, and fall back to the MSIE JS engine if V8 does not initialise correctly for some reason. There's a few machine-dependent bits:
  • V8 depends on the Visual C++ 2013 runtime (msvcp120.dll and msvcr120.dll)
  • MSIE depends on the version of Internet Explorer installed
You can disable the MSIE fallback by doing .SetAllowMsieEngine(false) in your config.


So as I've expected there is a strong relation between the error and the environment itself! Therefore, I've installed the latest version on Visual C++ 2013 runtime and checked Internet explorer version. but nothing worked.

Then I've found this post  were Andrey Taritsyn describes how to register Reactjs.net with Chakracore and test it on the server. but it still didn't work. After some more digging, I found out that even though JavaScriptEngineSwitcher.ChakraCore is in the packages, there is no dependency to Microsoft.ChakraCore  and therefore it cannot find the related dll for it :|.

Finding What is wrong

Reactjs.net uses System.Diagnostics.Trace to log the errors. Since you do not have access to console on test/ prod environment, you can just enable it to write to a log file:

To do so, go to web.config and add this:
 
<configuration>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="log" type="System.Diagnostics.TextWriterTraceListener" initializeData="output.log" />
</listeners>
</trace>
</system.diagnostics>
</configuration>

The solution

  1.  add Microsoft.ChakraCore nuget package
  2.  in your visual studio, go to App_start folder and create a class JsEngineSwitcherConfig

  3.  
     public class JsEngineSwitcherConfig
    {
    public static void Configure(JsEngineSwitcher engineSwitcher)
    {
    engineSwitcher.EngineFactories
    .AddChakraCore()
    //.AddJint() //only if needed
    //.AddJurassic()//only if needed
    .AddMsie(new MsieSettings
    {
    UseEcmaScript5Polyfill = true,
    UseJson2Library = true
    })
    .AddV8()
    ;
    engineSwitcher.DefaultEngineName = ChakraCoreJsEngine.EngineName;
    }
    }


  4.  Go to the Application_Start on Global.asax.cs and then add configure method to it. it should look like this:
  5.  
    protected void Application_Start()
    {
    .....
    
                RouteConfig.RegisterRoutes(RouteTable.Routes);
    
                JsEngineSwitcherConfig.Configure(JsEngineSwitcher.Instance);
    .......
    }


You are good to go 😀