I'm trying to serialize an object to JSON string as shown below:
new JavaScriptSerializer().Serialize(person)
Here, person is the object which is having lot of attributes such as name, address, city, state, etc but I have decorated the class as shown below so that it'll serialize only name and address.
using System;
using System.Runtime.Serialization;
namespace DataAccess.Models
{
[Serializable]
[DataContract]
public class Person
{
public string Id { get; set; }
[DataMember(Name = "full-name")]
public string Name { get; set; }
[DataMember(Name = "address")]
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
}
But when I run the program, the new JavaScriptSerializer().Serialize(person) gives me JSON with all the data including Id, City, State, Zip.
Why is it not giving me only full-name & address? It seems like it is completely ignoring these DataMember attributes.
When I use JsonConvert.SerializeObject(person) from Newtonsoft, everything works perfect & it serializes only Name & Address but JavascriptSerializer is giving all data.
Can any one tell me what could be the issue?
Consider using the [ScriptIgnore()] Attribute on those properties you don't want to be serialized.
http://msdn.microsoft.com/en-us/library/system.web.script.serialization.scriptignoreattribute(v=vs.100).aspx
See here for a detailed list of how the JavaScriptSerializer will handle different types: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.110).aspx
Edit:
Note that the JavascriptSerializer is not aware of the DataMember attributes and they therefore will not be used by the JavascriptSerializer (JSON.net will use them, but JSON.Net also defines it's own constructs for this: [JsonIgnore()] [JsonObject] and many other attributes support custom-naming). To accomplish this, try using the DataContractJsonSerializer in the System.Runtime.Serialization.Json namespace with some draw-backs.
See this question and answer for additional information:
JavaScriptSerializer.Deserialize - how to change field names
Related
How can we form an OData query to access the Name property of complex property ProductDetails in the ProductDTO class?
public class ProductDTO
{
public int Id { get; set; }
public string ProductName { get; set; }
public string Description { get; set; }
public ProductDetails ProductDetails { get; set; }
}
public class ProductDetails
{
public string Name { get; set; }
public string Price { get; set; }
public string Discount { get; set; }
public string ManufacturedDate { get; set; }
}
This query gives me ProductDetails:
/Products?$select=ProductDetails
{"#odata.context":"http://localhost:59909/$metadata#Products(ProductDetails)","value":[{"ProductDetails":{"Name":"Laptop","Price":"100299","Discount":"1000","ManufacturedDate":"12:01:2016
09:30:875"}}]}
According to this post, this isn't possible for a $select. However, it isn't clear what you are trying to achieve from your question so I thought I would post this in case it helps. For a single object, you can get the value of a nested property like this, here is an example using the TripPin example OData service: http://services.odata.org/V4/TripPinServiceRW/Airports('KLAX')/Location/Address/$value Here, the Location property is a complex type and we are getting just the value of the Address property on that object.
Try to use $expand clause
In my situation i had to add a complexType first:
builder.ComplexType<BalanceSheet>();
Additionally I found that different query should be used to get the complex type on UI
Instead of calling http://url/api/AccountDetails?$select=name,accountNumber,balance another url should be used:
http://url/api/AccountDetails?$select=name,accountNumber,balance&$expand=balance
you can only see complex properties like balance via $expand
Also, important to have $expand feature turned on. To do that add it before you add the edm model:
endpoints.Select().Expand().Filter().OrderBy().Count().MaxTop(10);
endpoints.MapODataRoute("odata", "odata", this.GetEdmModel());
See details here: https://stackoverflow.com/a/55476645/2050539
I have a model called Project
public class Project
{
[Key]
public int ID { set; get; }
public string Title { set; get; }
public string Image { set; get; }
public double? gained { set; get; }
}
I use this model with two stored procedures one returns all the properties and the other without the property gained. And I got this error
The data reader is incompatible with the specified 'Test.Models.Project'. A member of the type, 'Gained', does not have a corresponding column in the data reader with the same name.
I don't want to write separate models for each stored procedure.
How to solve that please ?
The datareader is kind of dumb in the sense that it will only match what was sent back to it. If a column is missing, it fails, as you can see.
The easiest way to solve this would be to update your second SELECT statement in your stored procedure to pass back a column named gained.
SELECT ID, Title, Image, NULL as gained FROM table
Here, we are passing back no data (NULL) as the gained column. This should make the data reader happy, keep you from needing multiple models and not send back any extra data.
The other possibility would be to use inheritance in your models. Have a base model that does not include gained, and have a second model that inherits from the base model that does include gained.
public class ProjectBase
{
[Key]
public int ID { set; get; }
public string Title { set; get; }
public string Image { set; get; }
}
public class ProjectGained : ProjectBase{
public double? gained { set; get; }
}
I'm using CodeFirst with MVC 3 and have these two classes:
public class Person
{
public int PersonId { get; set; }
[Email]
[Required]
public string Email { get; set; }
public string Passwort { get; set; }
public virtual City City { get; set; }
}
public class City
{
public int CityId { get; set; }
[Required]
public string Name { get; set; }
public virtual IEnumerable<Person> Persons { get; set; }
}
When adding a new person I want to reference a city to this person. Therefore i'm using a SelectList with all cities in my view. The CityId and the object is transferred correctly to the Post-method, but when saving the changes to the database I will have a new object in the city-table (with same name, but new Id).
I suggest there's something wrong with the relations in my models. Maybe somebody can help me.
If you give your Person model an explicit CityId property, then you won't need to retrieve the City object from your repository, you can just assign the CityId value directly to the Person object and save it. For really straightforward views, you don't need to use a viewmodel either, you could receive a Person instance into the POST action method and CityId would already be assigned, assuming the html field in the View has the same name.
This should fix your problem, because you will then know you are explicitly using a CityId that already exists.
Your database will already contain a Person.City_CityId field anyway so you're not creating anything new, just giving yourself more control over the situation. Sometimes you may need to use a [ForeignKey] attribute in the model to connect the Person.CityId property with the virtual property, but using the standard naming convention this shouldn't be necessary.
Assume I have an ASP.NET MVC 3 Controller that looks like this
public class MyController : Contoller
{
public ActionResult Edit(MyModel model)
{
/* doing some stuff with the model */
}
}
The model looks like this
public class MyModel
{
public string Property1 { get; set; }
public string Property2 { get; set; }
public ThatModel Property1 { get; set; }
public List<ThisModel> BunchOfThisModel { get; set; }
}
public class ThatModel
{
public string Property1 { get; set; }
public string Property2 { get; set; }
public string Property3 { get; set; }
public string Property4 { get; set; }
public string Property5 { get; set; }
public string Property6 { get; set; }
}
public class ThisModel
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
Does ASP.NET MVC or .NET (v4 is ok, v4.5 not) provide any built-in means to encode a model (say MyModel in this case) so that it can be sent to an action as form url encoded (aka x-www-form-urlencoded)? An example would be "property1=abc&property2=def". However, ASP.NET MVC has its own way to deal with nested models etc when decoding the request back to the model. Assume I'm simulating a browser using the WebRequest/WebResponse APIs provided since .NET 1.1.
In essence, I'd like to build up requests in tests to verify that
some data is excluded through binding, if needed
the anti forgery token is set, if needed
malicious data is handled accordingly
Note: ASP.NET Web API is not being used at this stage. Because I'm writing (integration) tests for an existing application, sending the model as JSON, XML or another alternative format isn't applicabile to the question.
I hope I've understood this question correctly, but provided you are 'POST'ing that data (from JSON?) then it is able to build up the model using a best-guess process.
Property names are matched, so if you sent (guessing the duplicate Property1 is actually Property3 here)
{
Property1="this",
Property2="that",
Property3={Property1="this3", ....},
BunchOfThisModel=[{Property1="bunchthis"},{....}]
}
This would populate your POCO with whatever names matched. If you left out a property (i.e. Property2) it would take on it's default(T) value.
Sending your object model in a GET request would be much more complicated, you could base64 the JSON string, and then parse it on server which is popular approach, but given it's a complex model POST might work best for your intentions.
You can also use a CustomBinder (a good article is here). You can also control which properties are bound to your POCO object by using the BindAttribute with the Exclude/Include options.
Hope I haven't missed the point and this proves useful :)
We have a model class defined that I want to produce from our EF 4.0 edmx for persistence. The class looks roughly as follows:
[DataContract]
public class Schedule
{
[DataMember]
public string Name { get; set; }
[DataMember]
public Guid Id { get; set; }
[DataMember]
public DateTime RunDate { get; set; }
[DataMember]
public IList<Guid> Routes { get; set; }
[DataMember]
public IList<Guid> Paths { get; set; }
}
How do I represent Routes and Paths on the edmx design surface? I can't see anyway of doing this other than creating two entities with a single Guid Id field then setting a 1-* Association to Schedule. I'd rather not have to do that as we'll then have a Route and Path class that isn't what we want at the moment.
We haven't had chance to look at Code First yet and don't really have time to figure it out for this project but would it support our needs?
Thanks for any assistance.
You must either use related entities or you musn't map them directly. You can for example map another fields called RoutesSerialized and PathsSerialized which will be of type string and contains all Guids stored as strings and separated by semicolon. Your current properties will use return IEnumerable and use internally use functions like String.Join, String.Split, ToString and Guid.Parse.