We just started a new ASP.Net project that uses web services to serialize some CSLA business objects into JSON data for our client javascript/JQuery code. After reviewing the JSON data in the client browser(Firebug in Firefox) we notices that there are a significant number of properties from the business object that we do not need downloaded to the browser.
Is there a way to exclude properties (other than marking them private) from getting serialized by the JSON serializer? We are not calling the JSONSerializer directly, but instead just included a ScriptMethod declaration on the WebMethod.
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
<WebMethod()> _
Public Function getQuestions()
UPDATE
We tried the suggestion of adding the attribute on the public property but received an error:
Error 25 Attribute 'NonSerializedAtrribute' cannot be
applied to 'Name' because the attribute is not valid
on the is declaration type.
Now if we add NonSerialized to the class then it works but not on the property. However, we do want some properties to be serialized.
Any ideas?
You should use ScriptIgnore attribute for all properties which should be not serialized.
If you decide to make more customization of data serialization, for example, replacing one properties name with another one or converting some properties in an array and so on you can write a small JavaScriptTypeResolver which do it.
ScriptIgnore should do the job for you as sugested by Oleg. Check out this link for a detailed sample
you could try to place a NonSerializedAttribute on the properties not sure if it works with the Json serializer...
Edit: if you are using .net 4.0 you could try to use the ISerializable interface...
Related
I have two applications which are communicating via rest API, serialized via Json.NET
The part that i am having difficulties with is passing an inheritance structure between the two applications:
ChildClass1 : BaseClass
ChildClass2 : BaseClass
I need to be able to deserialize a list of BaseClasses that have each individually been deserialized into their correct relative type:
JsonConvert.DeserializeObject<IEnumerable<BaseClass>>(json)
I am aware of the TypeNameHandling.All Serializer setting, but the problem i have is that the class on each application are in different namespaces:
Application 1:
App1.NameSpace.ChildClass1
Application 2:
App2.DifferentNameSpace.ChildClass1
Due to this it is not automatically converting them. It is not possible to change the namespaces or use a contract library for these classes.
Do i need to write a custom JsonReader? or is there a setting i can use to override the class name when being serialized / deserialized so that i can remove the namespace?
You can use an ISerializationBinder you set on the settings that allow you to specify the name to use in JSON during serialization and what type to use on deserialization.
That way you have full control over the names to use.
An example can be found here.
I am trying to serialize a JSON object to send it from the Controller to the View. Despite reading plenty of similar questions, I did not find a solution that works well.
In my case, I have a List<MyType> object, where is a pre-compiled class. But when I tried to serialize the data by means of:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(MyType));
I got the following error:
Additional information: Type MyType cannot be
serialized. Consider marking it with the DataContractAttribute
attribute, and marking all of its members you want serialized with the
DataMemberAttribute attribute.
However, since it is a pre-compiled class, I cannot mark the members. How can I solve this?
The DataContractJsonSerializer uses opt-in semantics, which means that you must mark the class(es) to be serialized with a [DataContract] attribute, and mark all members of those classes that you want serialized with [DataMember]. If you cannot change the classes (because they are precompiled or you don't otherwise control the source code), then there's not much you can do with this serializer short of copying the data into another class that can be serialized. But, with ASP.NET MVC you shouldn't really be using DataContractJsonSerializer anyway-- this serializer was created for WCF and is not very flexible or user-friendly, IMO.
The ASP.NET MVC framework has a Json method built into the base controller, which uses the JavaScriptSerializer behind the scenes to serialize your model objects. This serializer does not require marking up classes with attributes, and because it is baked-in you don't have to put any special serialization code into your controller methods to use it. Just change your method to return JsonResult instead of ActionResult, then pass your object to the Json method as a last order of business.
For example:
[HttpGet]
public JsonResult GetItem(int id)
{
PrecompiledClass pc = RetrieveObjectFromDatabaseOrWhatever(id);
return Json(pc, JsonRequestBehavior.AllowGet);
}
The JavaScriptSerializer does have some limitations that I won't go into here, which you probably won't hit in most normal circumstances. But if you do find that the JavaScriptSerializer does not suit your needs, you can switch to a robust third-party serializer like Json.Net. See ASP.NET MVC and Json.NET and Using JSON.NET as the default JSON serializer in ASP.NET MVC - is it possible? to learn more about that option.
I would not recommend using a precompiled class as your view model. Separation of concerns and whatnot.
Create a new class, MyTypeViewModel, which will have only the properties that the UI needs to know about, and map the properties from MyType to MyTypeViewModel. Then return like this in your controller method if you're returning this result as part of an API call:
return Json(myTypeViewModel, JsonRequestBehavior.AllowGet);
or return View(myTypeViewModel) if you want to render an entire view.
Does anyone know if there is an alternative to using attributes on C# properties to map to XML nodes when using XmlSerializer?
My issue is that I have an object called Article, with some properties (e.g. ID, Title, Body) and I do not want to add attributes directly to it (used elsewhere, etc, etc)...so I created a partial class and re-defined the properties and added the attributes there, but soon discovered that you cannot have duplicate properties in partial classes.
So I was wondering if anyone knew of any way that I could map the properties instead (in a similar fashion to n-hibernate, for example).
I'd appreciate any help.
There's a constructor of the XmlSerializer class that allows you to pass a XmlAttributeOverrides and thus alter the behavior at runtime.
Quote from the documentation:
The overrides parameter can be used to control how fields and
properties are encoded in XML. These settings override any attributes
that already exist on the objects. This can be useful when the source
code cannot be modified or multiple encodings are required for the
same classes.
You could implement IXmlSerializable directly. It requires some more code, but you will have full control without the need for attributes.
I used DataContractSerializer to save user data but now
I want to use DataContext for my database design.
But the system existed struture as below cannot be stored through DataContext.
class Data
{
public DataType1;
public DataType2;
}
It seems these APIs cannot support storing user defined data type.
I don't want to separate all data members because this system uses these structure every where. If I changed the structure, it is hard to maintain and the DataType1 contains a List<> member. I don't know how to do even though separating
this structure.
Could you please kindly to give me some suggestions?
Thanks.
It seems these APIs cannot support storing user defined data type
If that were true the api would be completely without purpose.
The DataContractSerializer has what appear to be conflicting rules in an attempt to make serialisation more implicit. You can for example serialise a public type that has public properties and a public default constructor without having to decorate it with a DataContract attribute or any of its members with a DataMember attribute.
Looks to me that at the very least you need make Data a public class. Most likely you would need to review your other classes to ensure that either they are implicitly serializable or that you explictly mark them up with the DataContract and DataMember attributes.
Dear all:
But now I used DataContext
DataContext cannot serialize the user defined type even marked [Serializable].
The workaround seems to separate all the members into one class now.....
Thanks.
I am in the process of designing an itemization system for a game. I am creating a bunch of interfaces (IItem, IConsumable, IEquipable, IWeapon, etc...) to define what type of functionality is possible with items and then a number of classes (Weapon, Potion, etc...) the define the actual item types.
Now when saving out the player, the data is going to be stored as a JSON file (using the JSON.NET library) and will included the players inventory which will include these items. The issue is that when I try to deserialize the JSON file to an object when reading in the file, how will I be able to tell the JSON.NET library what type of class this is?
One thing I thought of and have not had time to try yet is that all my objects that get serialized into JSON have a DTO version of the object that is used in conjunction with the JSON.NET library. What I though about trying is maybe I could add in a property to the DTO called ClassType and then when reading the file into the application, I would first read the object in as an anonymous type. Then based on the ClassType property, I would convert it to the proper type. The 2 issues I have with this is that 1. it seems like a very ugly solution and 2. I am not even sure if that is possible.
(Copied from this question)
In cases here I have not had control over the incoming JSON (and so cannot ensure that it includes a $type property) I have written a custom converter that just allows you to explicitly specify the concrete type:
public class Model
{
[JsonConverter(typeof(ConcreteTypeConverter<Something>))]
public ISomething TheThing { get; set; }
}
This just uses the default serializer implementation from Json.Net whilst explicitly specifying the concrete type.
The source code and an overview are available on this blog post.
You should know the concrete type when you are serializing. So you can use TypeNameHandling of JSON.NET.
http://james.newtonking.com/archive/2010/08/13/json-net-3-5-release-8-3-5-final.aspx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+jamesnewtonking+%28James+Newton-King%29