PDA

View Full Version : [CLOSED] JsonSerializerSettings breaks TriggerField



RCN
Dec 01, 2014, 6:42 PM
After more than 5 hours i was able to find what was breaking TriggerField :(

When JSON.GlobalSettings is set to new Newtonsoft.Json.JsonSerializerSettings() (Global.asax line 5), the FieldTrigger does not work as expected.

Error
http://forums.ext.net/attachment.php?attachmentid=16831&stc=1

It was supposed to be:
http://forums.ext.net/attachment.php?attachmentid=16841&stc=1

Global.asax


public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
JSON.GlobalSettings = new Newtonsoft.Json.JsonSerializerSettings();

AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

}

protected void Application_AuthenticateRequest(object sender, System.EventArgs e)
{
string url = HttpContext.Current.Request.FilePath;

if (url.EndsWith("ext.axd"))
{
HttpContext.Current.SkipAuthorization = true;
}
}

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{extnet-root}/{extnet-file}/ext.axd");

routes.MapRoute("Default", "{controller}/{action}");
}
}




<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
</head>
<body>
<ext:ResourceManager runat="server" SeparateUIStyles="false" Theme="Gray" />

<ext:DropDownField Margin="10"
ID="_ddd"
Editable="false"
Width="800"
runat="server">
<Triggers>
<ext:FieldTrigger Icon="Clear" Weight="-1" />
</Triggers>
<Component>
<ext:Panel Title="Inner Panel" runat="server" Height="600">
<Loader Url="http://www.ext.net" Mode="Frame" runat="server" />
</ext:Panel>
</Component>
</ext:DropDownField>
</body>
</html>




Unfortunately in my scenario was pretty more difficult to find what was going on because i use ComponentLoader to render the page contents, so, i had to "deconstruct" my application to a smaller (smallest) scenario to be able to identify the issue



<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<script type="text/javascript">
var DocumentReady = function () {
ProcessContent(App._hdnContent.value, BindContent);
}
var ProcessContent = function (content) {
content = Ext.decode(content, true);
var auxContent = content;
if (auxContent && auxContent['x.res']) {

if (auxContent.config) {
content = Ext.decode(auxContent.config, true);
}

if (auxContent['x.res'].ns) {
Ext.ns.apply(Ext, auxContent['x.res'].ns);
}

if (auxContent['x.res'].res) {
Ext.net.ResourceMgr.load(auxContent['x.res'].res, function () {
BindContent(content);
});
}
else {
BindContent(content);
}
}
else {
BindContent(content);
}
}
var BindContent = function (content) {
if (content != null) {
App._vwp.add(content);
}
App._hdnContent.destroy();
}
</script>
</head>
<body>
<ext:ResourceManager runat="server" Theme="Gray">
<Listeners>
<DocumentReady Handler="DocumentReady();" Delay="1000" />
</Listeners>
</ext:ResourceManager>
<ext:Hidden ID="_hdnContent" Text="<%# ViewBag.ApplicationContent %>"
AutoDataBind="true" runat="server" />
<ext:Panel ID="_vwp" Padding="10" Width="300" Layout="FitLayout" Border="false" runat="server">
</ext:Panel>
</body>
</html>





public class ExampleController : System.Web.Mvc.Controller
{
public ActionResult Index()
{
SelectBox sb = new SelectBox
{
FieldLabel = "Ext.Net",
};
sb.Items.Add(new ListItem { Text = "E", Value = "1" });
sb.Items.Add(new ListItem { Text = "X", Value = "2" });
sb.Items.Add(new ListItem { Text = "T", Value = "3" });

sb.Triggers.Add(new FieldTrigger { Icon = TriggerIcon.Clear, Weight = -1 });

ViewBag.ApplicationContent = ComponentLoader.ToConfig(sb);

return View();
}
}

RCN
Dec 01, 2014, 6:52 PM
The following image shows the difference when TriggerField is serialized using JSON.GlobalSettings is set to new Newtonsoft.Json.JsonSerializerSettings

16851

Thanks in advance

RCN
Dec 01, 2014, 6:59 PM
That's why i use Newtonsoft.Json.JsonSerializerSettings: http://forums.ext.net/showthread.php?26135-CLOSED-The-best-approach-to-serialize-an-enum-as-its-value

Daniil
Dec 08, 2014, 1:37 PM
Hi Raphael,

If a developer changes the JSON.GlobalSettings or RequestSettings, he is responsible for how the things are serialized.

It is how the GlobalSettings property looks by default.


private static bool readFromConfig = false;

private static JsonSerializerSettings globalSettings = new JsonSerializerSettings {
Converters = JSON.Converters,
DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Unspecified,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};

public static JsonSerializerSettings GlobalSettings
{
get
{
if (!JSON.readFromConfig)
{
JSON.globalSettings.DateTimeZoneHandling = GlobalConfig.Settings.DateTimeZoneHandling;
JSON.readFromConfig = true;
}

return JSON.globalSettings;
}
set
{
JSON.globalSettings = value;
}
}

All the settings are quite essential for proper Ext.NET serialization.

When you use this

JSON.GlobalSettings = new Newtonsoft.Json.JsonSerializerSettings();
all the settings are being reset.

Well, it is the reason why a TriggerField is not serialized correctly.

I am not sure what to suggest, because I don't know why you reset the GlobalSettings. Please elaborate on that.

RCN
Dec 08, 2014, 1:50 PM
That's why i used Newtonsoft.Json.JsonSerializerSettings: http://forums.ext.net/showthread.php?26135-CLOSED-The-best-approach-to-serialize-an-enum-as-its-value > http://forums.ext.net/showthread.php?26135-CLOSED-The-best-approach-to-serialize-an-enum-as-its-value&p=115834&viewfull=1#post115834



All the settings are quite essential for proper Ext.NET serialization.


I completely agree with you.

At this time i prefer to stop overriding JSON.GlobalSettings since i can break the application if i do so.

The purpose of this thread was to inform to others who may also overriden as i did.

Thank you Daniil, once again.

Please mark this thread as closed.

RCN
Dec 27, 2014, 9:04 PM
On my scenario, i was able to stop overriding JSON.GlobalSettings, but as stated on http://forums.ext.net/showthread.php?26135-CLOSED-The-best-approach-to-serialize-an-enum-as-its-value i need to serialize enum as its value, so i needed to remove StringEnumConverter from JSON.GlobalSettings.Converters, as shown below:



protected void Application_Start()
{
JsonConverter stringEnumConverter = JSON.GlobalSettings.Converters.FirstOrDefault(conv erter => converter is StringEnumConverter);

if (stringEnumConverter != null)
{
JSON.GlobalSettings.Converters.Remove(stringEnumCo nverter);
}
}

RaphaelSaldanha
Jan 06, 2015, 1:03 PM
Just one more information:

FieldTrigger requires Ext.Net.JRawValueJsonConverter, which is not defined by default in JsonSerializerSettings;

It's possible to overcome the issue by adding JRawValueJsonConverter to JsonSerializerSettings' converters


protected void Application_Start()
{
JsonSerializerSettings settings = new JsonSerializerSettings();

settings.Converters.Add(new Ext.Net.JRawValueJsonConverter());

JSON.GlobalSettings = settings;
}


But as stated by Daniil (http://forums.ext.net/showthread.php?26135-CLOSED-The-best-approach-to-serialize-an-enum-as-its-value&p=115834&viewfull=1#post115834): Be careful to override the GlobalSettings. It affects all serialization in Ext.NET and it can break something