Aasim
Aasim

Reputation: 143

Validating structure of Json object in WCF Rest Service

I have written a WCF Rest Service, where in POST method Json Object is received as StudentDetails. Now i want to validate its structure that it should not contain extra fields/information than the specified fields.
Below is my service(ServiceContract)

namespace RestService
{

[ServiceContract]
public interface IRestService
{
[OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "/SaveStudent", RequestFormat =WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json)]
    string SaveStudent(StudentDetails studentDetails);
}

[Serializable]
public class WebServiceDictionary : ISerializable
{
    public Dictionary<string, string> Entries { get; }

    public WebServiceDictionary()
    {
        Entries = new Dictionary<string, string>();
    }
    public WebServiceDictionary(SerializationInfo info, StreamingContext context)
    {
        Entries = new Dictionary<string, string>();
        foreach (var entry in info)
            Entries.Add(entry.Name, entry.Value.ToString());
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        foreach (var entry in Entries)
            info.AddValue(entry.Key, entry.Value);
    }
}

[DataContract]
public class StudentDetails
{

    [DataMember]
    public WebServiceDictionary StudentDetail { get; set; }
}
}

This is implementation of Service

namespace RestService
{

public class RestService : IRestService
{

    public string SaveStudent(StudentDetails studentDetails)
    {
        SqlHelper sql = new SqlHelper();
        sql.OpenConnection();

        WebServiceDictionary student = studentDetails.StudentDetail;



        if (student.Entries.Keys.Count != 3)
        {
            WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
            return null;
        }
        sql.SaveJson(student.Entries["Name"], student.Entries["Address"], int.Parse(student.Entries["Grade"]));
        sql.CloseConnection();

        return "Passed";
    }
}
}

So the Structure of Json should be

{
"StudentDetail" : 
{
    "Name" : "ABC", "Address" : "ABC", "Grade":"10"
}
}

I have put checks for not letting the request accepted when there is/are some fields are missing and it is working fine. Now i want that when Json data contains one or more extra information, the request should fail(BadRequest). For example if Json object is:

{
"StudentDetail" : 
{
    "Name" : "ABC", "Address" : "ABC", "Grade":"10", "Extra" : "Item"
}
}

As Extra item is present so it should fail(BadRequest). And also

{
"StudentDetail" : 
{
    "Name" : "ABC", "Address" : "ABC", "Grade":"10"
},
"New" : { "key" : "value" }

}

As extra "New" item is introduced so it should fail(BadRequest).

Please help me. Thanks

Upvotes: 1

Views: 541

Answers (1)

Mohammad
Mohammad

Reputation: 2764

unfortunately you cant do this with wcf. in web api you simply can use dynamic object and validate the input. but in wcf you have to use an object like this:

[Serializable]
public class WebServiceDictionary : ISerializable
{
    public Dictionary<string, string> Entries { get; }

    public WebServiceDictionary()
    {
        Entries = new Dictionary<string, string>();
    }
    public WebServiceDictionary(SerializationInfo info, StreamingContext context)
    {
        Entries = new Dictionary<string, string>();
        foreach (var entry in info)
            Entries.Add(entry.Name, entry.Value.ToString());
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        foreach (var entry in Entries)
            info.AddValue(entry.Key, entry.Value);
    }
}

then your input will be like this:

[DataContract]
public class StudentDetails
{

    [DataMember]
    public WebServiceDictionar StudentDetail { get; set; }
}
}

now you can access to the StudentDetail like this:

StudentDetail.Entries[Name]

and then validate it. at first you can get all the keys in your dictionary like this:

var keys=Entries.Keys;

then you can validate them like this:

if(keys.length!=3)
//its not valid
if(!keys.contain("Address"))
//its not valid
.
.
.

Upvotes: 1

Related Questions