I am using Json.NET to serialize an object to be sent to a compact framework 3.5 device (lucky me).
My class on the compact device is:
public class Specification
{
public Guid Id { get; set; }
public String Name { get; set; }
public String Instructions { get; set; }
}
The Json being returned sent to the device is (notice the null for instructions):
string json = #"{""Name"":""Test"",""Instructions"":null,""Id"":""093a886b-8ed4-48f0-abac-013f917cfd6a""}";
...and the method being used to deserialize the json is...
var result = JsonConvert.DeserializeObject<Specification>(json);
On the server I'm using the following to create the Json:
var serializer = new JsonSerializer();
serializer.Formatting = Formatting.None;
serializer.Serialize(context.HttpContext.Response.Output, this.Data);
The problem is that on the compact framework, it's failing to put a value into result.Instructions which is causing a null reference when it is referenced later in the code.
I'm using Newtonsoft.Json.Compact v3.5.0.0 (I think that's the latest version), and on the server I'm using Newtonsoft.Json 4.5.0.0.
Question
How can I either:
a) Change the server code to stick a "" instead of a null value in where a string is null.
or
b) Change the compact framework code to be able to handle null value strings.
Things I've tried
I've been looking through the documentation/examples of Json.Net and have tried a multitude of things like a implementing a DefaultContractResolver, and a custom JsonContract. Maybe the answer lies within those but my lack of understanding of Json.Net at this level isn't helping!!
Further info
I was using System.Runtime.Serialization.Json.DataContractJsonSerializer for the server side serialisation, which did generated quotes in the event of empty strings. Unfortunately, I need more flexibility with the serialization which is why I've started using Json.Net.
Any hints/tips appreciated.
OK - no answers, but having search all yesterday afternoon I went to bed, and search again this morning to find: Serializing null in JSON.NET, which pretty much answers my question.
Related
Hey there StackOverflow enthusiasts.
I am attempting to update an old site of mine to the newest edition of Asp.net MVC4. It was previously on MVC2, and on MVC2 it allowed me to pretty much separate my jquery and client side stuff from any of the backend stuff. But I guess with MVC4 they want you to have a lot of your validation stuff tied directly to your models and so on.
But I have a client side jquery validation script that was working pretty well before, and I was wondering, how can I get it to work again. Specifically, I had a field that would not be validated if the user entered in more than 4000 characters. Otherwise it would not be required. Here is the client side code that worked before in MVC2....
Comment: {
required: function (element) {
return $(element).val().length > 4000;
},
maxlength: 4000
}
and the message that would be displayed if validation was not passed...
messages: {
...
Comment: 'Why dont you stop attempting to put in more than 4000 characters? Thanks...'
}
How can I do that with MVC four? To get anything to display in another field I noticed I needed to put a required over the field in my model...
[Required(ErrorMessage = "Please select an Admit Date")]
public DateTime? AdmitDate { get; set; }
Is there a way to write a requirement function so that it is only required under certain circumstances? I would prefer to keep it client side to keep my concerns separate if you know what I mean. Any help would be appreciated.
You can use [Required] and [StringLength] to constrain the input on your Comment.
[Required(ErrorMessage = "Please fill in a comment")]
[StringLength(4000, ErrorMessage = "Why dont you stop attempting to put in more than 4000 characters? Thanks...")]
public string Comment { get; set; }
Conditional required constraints are not covered by default data annotations. The default way of handling 'complex' validations is by implementing the IValidatableObject interface on your model.
However, since you are looking for a client-side solution, we can look at other frameworks that may solve this problem for you. For instance, MVC Foolproof Validation supports a [RequiredIf] attribute that also works client-side.
I'm new to WCF data services. I have a quite simple data model. Some of its properties have the same type, like this:
public IQueryable<IntegerSum> HouseholdGoodsSums
{
get
{
return GetData<IntegerSum>(DefaultProgramID, "rHouseholdGoodsPrice", IntegerSumConverter);
}
}
public IQueryable<IntegerSum> StructureSums
{
get
{
return GetData<IntegerSum>(DefaultProgramID, "rStructurePrice", IntegerSumConverter);
}
}
The IntegerSum is a very very simple class:
[DataServiceKey("Amount")]
public class IntegerSum
{
public int Amount { get; set; }
}
When I navigate to my service in a web browser, I see the following error message:
The server encountered an error processing the request. The exception message is 'Property 'HouseholdGoodsSums' and 'StructureSums' are IQueryable of types 'IntegrationServices.PropertyIntegrationServices.IntegerSum' and 'IntegrationServices.PropertyIntegrationServices.IntegerSum' and type 'IntegrationServices.PropertyIntegrationServices.IntegerSum' is an ancestor for type 'IntegrationServices.PropertyIntegrationServices.IntegerSum'. Please make sure that there is only one IQueryable property for each type hierarchy.'.
When I get rid of one of these two properties, the service starts working.
I searched for this error message in google, but haven't found a solution.
Is it really not allowed to have two properties with the same type in a data model? If so, why?
Comrade,
To address the error first, you're running into a limitation in the Reflection provider. Specifically, the Reflection provider doesn't support MEST.
That said, there are better approaches to achieve what you're trying to achieve. You should probably not make IntegerSum an entity type (an entity type is a uniquely identifiable entity, which doesn't really fit your scenario). While you can't expose that directly, you can expose it as a service operation. That seems much closer to what you're trying to achieve.
A couple of ways to distinguish between whether or not something should be an entity:
If it has a key already, such as a PK in a database, it should probably be an entity type
If you need to create/update/delete the object independently, it must be an entity type
HTH,
Mark
I have a WCF service in which I have some data contracts. I'm using web service software factory, which uses a designer to create all the message and data and other contracts, and it creates them as partial classes. When the code is regenerated the classes are recreated.
using WcfSerialization = global::System.Runtime.Serialization;
[WcfSerialization::CollectionDataContract(Namespace = "urn:CAEService.DataContracts", ItemName = "SecurityItemCollection")]
public partial class SecurityItemCollection : System.Collections.Generic.List<SecurityItem>
{
}
The data contract is a generic List of a custom class which was working fine. However I now want to add a property to this class, so I added this partial class in the same namespace:
public partial class SecurityItemCollection
{
public int TotalRecords { get; set; }
}
This seems to work fine on the service side, but when I compile and then update the service reference from the client, the class doesn't have the new property i.e. when it serialises it and recreates it on the client side, it's missing the new property. Anyone know why this is?
TIA
EDIT:
Ok this is officially driving me nuts. The only thing I can see is that it is using the CollectionDataContract attribute instead of DataContract. Does this somehow not allow data members in the class to be serialised? Why would that be? It is working fine on the service side - I can see and populate the values no problem. However when I update the service refernce on my client there's nothing, just the colelction class without the data member.
Try to add the DataMember attribute to the TotalRecords property
Ok after much searching I finally found out that this isn't allowed i.e. classes marked as CollectionDataContract can't have data members. Why this is I have no idea but it cost me several hours and a major headache. See link below:
WCF CollectionDataContract and DataMember
I know this is old but it kept coming up when I searched on this subject.
I was able to get this working by adding a "DataMemberAttribute" attribute to the property. Below is a code example.
public partial class SecurityItemCollection
{
[global::System.Runtime.Serialization.DataMemberAttribute()]
public int TotalRecords { get; set; }
}
I'm developing some RESTful services in WCF 4.0. I've got a method as below:
[OperationContract]
[WebGet(UriTemplate = "Test?format=XML&records={records}", ResponseFormat=WebMessageFormat.Xml)]
public string TestXml(string records)
{
return "Hello XML";
}
So if i navigate my browser to http://localhost:8000/Service/Test?format=XML&records=10, then everything works as exepcted.
HOWEVER, i want to be able to navigate to http://localhost:8000/Service/Test?format=XML and leave off the "&records=10" portion of the URL. But now, I get a service error since the URI doesn't match the expected URI template.
So how do I implement defaults for some of my query string parameters? I want to default the "records" to 10 for instance if that part is left off the query string.
Note: This question is out of date, please see the other answers.
This does not appear to be supported.
However, Microsoft has been made aware of this issue and there is a work-around:
You can get the desired effect by
omitting the Query string from the
UriTemplate on your WebGet or
WebInvoke attribute, and using
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters
from within your handlers to inspect,
set defaults, etc. on the query
parameters.
https://connect.microsoft.com/VisualStudio/feedback/details/451296/
According to this answer this is fixed in .NET 4.0. Failing to supply the query string parameter seems to result in its being given the default value for the type.
Check this blog post out. Makes sense to me, and comes with a class to parse out the query string parameters.
http://blogs.msdn.com/b/rjacobs/archive/2009/02/10/ambiguous-uritemplates-query-parameters-and-integration-testing.aspx
Basically don't define the query string parameters in the UriTemplate so it matches with/without the parameters, and use the sample class to retrieve them if they're there in the method implementation.
This seems to work in WCF 4.0.
Just make sure to set your default value in your "Service1.svc.cs"
public string TestXml(string records)
{
if (records == null)
records = "10";
//... rest of the code
}
While this is an old question, we still come to this scenario from time to time in recent projects.
To send optional query parameters, I created WCF Web Extensions nuget package.
After installation, you can use the package like this:
using (var factory = new WebChannelFactory<IQueryParametersTestService>(new WebHttpBinding()))
{
factory.Endpoint.Address = new EndpointAddress(ServiceUri);
factory.Endpoint.EndpointBehaviors.Add(new QueryParametersServiceBehavior());
using (var client = factory.CreateWebChannel())
{
client.AddQueryParameter("format", "xml");
client.AddQueryParameter("version", "2");
var result = client.Channel.GetReport();
}
}
Server side you can retrieve the parameters using WebOperationContext:
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;
If i want to use Linq-SQL i also have to drag the DB Table unto the designer surface to create the entity classes.
I always like full control in my application and do not like the classes created by dotnet.
Is it possible to provide this connection between Linq and the DB using my own Data Access Layer Entity classes?
How can i get it done?
You can write your own classes very easily using Linq-to-SQL - just involves painting your classes with some Attributes.
For Example, this is a very simple table I have in one of my projects, and it works with Linq-to-SQL just fine:
[Table(Name = "Categories")]
public class Category : IDataErrorInfo
{
[Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int Id { get; set; }
[Column] public string Name { get; set; }
[Column] public string ExtensionString { get; set; }
}
The code was very easy, especially if you make your property names line up with your table names (you don't have to).
Then you just need a Repository to connect to the DB:
class CategoryRepository : ICategoryRepository
{
private Table<Category> categoryTable;
public CategoryRepository(string connectionString)
{
categoryTable = (new DataContext(connectionString)).GetTable<Category>();
}
}
Of course there is more to it, but this shows you the very basics and it is not hard to do once you understand it. This way you have 100% control over your classes and you can still take advantage of Linq-to-SQL.
I learned this approach from Pro ASP.NET MVC Framework, an awesome book.
If you want to see more, all of my Linq-to-SQL classes were written from scratch on one of my projects you can browse here.
To avoid drag & drop you can take a look at SqlMetal.exe.
However, it sounds like you really are requesting Persistence Ignorance, and I'm not sure that this is possible with L2S - it certainly isn't possible with LINQ to Entities until .NET 4...
I once wrote a blog post on using SqlMetal.exe and subsequently modifying the generated schema - perhaps you will find it useful, although it has a different underlying motivation.
I've got a couple tutorials up on CodeProject that walk through how to do this, including how to handle the relationships (M:M, 1:M, M:1) in an OO way and keep them in synch as you make updates:
A LINQ Tutorial: Mapping Tables to Objects
A LINQ Tutorial: Adding/Updating/Deleting Data