Validate ajax request with Data annotations - ajax

I am trying to use the Data-annotations to Validate an ajax request
var request = $.ajax({
url: "http://localhost:55555/WebService1.asmx/HelloWorld",
type: "POST",
data: JSON.stringify({
request: {
Id: '34',
Value: 'Hello World'
}
}),
contentType: "application/json; charset=utf-8",
dataType: "json"
});
Server side:
/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[ScriptService]
public class WebService1 : WebService
{
[WebMethod]
public string HelloWorld(TestClass request)
{
return request.Value;
}
}
public class TestClass
{
[Range(0,10)]
public string Id { get; set; }
[StringLength(2)]
public string Value { get; set; }
}
I was hoping that this would fail since my input parameters doesn't match my required attributes. But instead it works fine and I am able to create the class with my "non valid" parameters
What am I doing wrong?

Related

The registered message body readers compatible with the MIME media type are: application/json; charset=UTF-8

I am developing a phonegap application where I need to post JSON data from phonegap to rest web service.
ajax call:
var data = {"name" : "abc"};
$.ajax({
type: "POST",
// url: "http://192.168.3.243:8090/ws/welcome",
url: "http://192.168.3.243:8090/TestExample/rest/welcome",
// url: "http://192.168.3.125:8080/JustInReporter/rest/test",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "application/json",
success: function (response) {
console.log(" **** success ** "+response);
}
});
Rest service:
#Path("/welcome")
public class WelcomeImpl
{
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public WelcomeForm welcome(WelcomeForm welcomeFormObject)
{
WelcomeForm form = new WelcomeForm();
form.title = " Connected ... ";
System.out.println("welcomeFormObject *** "+welcomeFormObject.title);
return form;
}
}
#XmlRootElement
public class WelcomeForm
{
public String title;
public WelcomeForm()
{
title = "";
}
public WelcomeForm(String inTitle){
title = inTitle;
}
}
when I run the application I am getting this error at server side:
SEVERE: A message body reader for Java class com.test.beancls.WelcomeForm, and Java type class com.test.beancls.WelcomeForm, and MIME media type application/json; charset=UTF-8 was not found.
The registered message body readers compatible with the MIME media type are:
application/json; charset=UTF-8 ->
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
can you tell me where I am doing wrong.
You should try with a more specific bean. In your JSON, you are sending "name" attribute as a part of the main body. So you should have a matching data structure. This may also be accomplished via annotations but as a start this should suffice
public class WelcomeForm
{
public String name;
public WelcomeForm()
{
title = "";
}
public WelcomeForm(String inTitle){
name = inTitle;
}
public String getName(){ return name;}
public void setName(String name){ this.name = name;}
}
And rest service to accept your data can be:
#Path("/welcome")
public class WelcomeImpl
{
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public WelcomeForm welcome(WelcomeForm welcomeFormObject)
{
WelcomeForm form = new WelcomeForm();
form.title = " Connected ... ";
System.out.println("welcomeFormObject *** "+welcomeFormObject.title);
return form;
}
#POST
#Path("list")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public WelcomeForm welcome(WelcomeForm[] welcomeFormObjects)
{
// the path has changed to /welcome/list just to avoid ambiguity
// do whatever you do with the array of objects
}
}

Post two array as json through ajax to Spring Controller

My ajax method
$.ajax(
{
type: "POST",
contentType: 'application/json;charset=utf-8',
dataType:'json',
url: 'addrequisition',
data: JSON.stringify([{ ids: val, qty: valtxt }]),
success: function(result)
{
$("#result").html(result);
}
});
});
and my arrays are val and valtxt.
I want to read those arrays in a Spring Controller help me :)
First, you need to define a class in java like this:
class MyClass{
private String ids;
private String qty;
//Setters and Getters
}
Note that the members of class MUST be same as json data.
then in your controller you need to define action like this:
#RequestMapping(value = "/addrequisition", method = RequestMethod.POST)
public String addrequisition(#RequestBody MyClass myClass) {
String result = myClass.getIds() + myClass.getQty();
return result;
}

POST JSON with MVC 4 API Controller

I have this code:
$.ajax({
type: "POST",
url: "/api/slide",
cache: false,
contentType: "application/json; charset=utf-8",
data: '{"Title":"fghfdhgfdgfd"}',
dataType: "json",
An this is my controler:
public class SlideController : ApiController
{
// POST /api/Slide
public void Post(string Title)
{
}
When I run the code and call the /api/Slide, the [Title] has no data and is null.
How do I post JSON to the API controller?
POST http://127.0.0.2:81/api/slide HTTP/1.1
Host: 127.0.0.2:81
Connection: keep-alive
Content-Length: 18
Origin: http://127.0.0.2:81
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://127.0.0.2:81/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Title=fghfdhgfdgfd
Define a view model:
public class SlideViewModel
{
public string Title { get; set; }
}
then have your controller action take this view model as argument:
public class SlideController : ApiController
{
// POST /api/Slide
public void Post(SlideViewModel model)
{
...
}
}
finally invoke the action:
$.ajax({
type: 'POST',
url: '/api/slide',
cache: false,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ title: "fghfdhgfdgfd" }),
success: function() {
...
}
});
The reason for that is that simple types such as strings are bound from the URI. I also invite you to read the following article about model binding in the Web API.
Ensure the object you are trying to convert to has a default (empty) constructor.
Rule of thumb: If you want to deserialize to an object, you need to make it simple for the objects to be created. These guidelines can help:
All properties that are to be passed around must be public
the object needs to able to be constructed without any parameters.
This JSON string/object for example:
{ Name: "John Doe", Phone: "123-456-7890", Pets: [ "dog", "cat", "snake" ] }
can be converted to an object from the following class:
public class Person {
public string Name { get; set; }
public string Phone { get; set; }
public string[] Pets { get; set; }
}
or this one:
public class Person {
public string Name { get; set; }
public string Phone { get; set; }
public string[] Pets { get; set; }
public Person() {}
public Person(string name, string phone) {
Name = name;
Phone = phone;
}
}
or this one:
public class Person {
public string Name { get; set; }
public string Phone { get; set; }
public string[] Pets { get; set; }
public Person() {}
}
but not this one
public class Person {
public string Name { get; set; }
public string Phone { get; set; }
public string[] Pets { get; set; }
public Person(string name, string phone) {
Name = name;
Phone = phone;
}
}
Now let ASP.NET MVC 4 do the rest
public class PersonController : ApiController
{
// .. other actions
public HttpResponseMessage PostPerson(Person person)
{
if ( null != person)
// CELEBRATE by doing something with your object
else
// BE SAD and throw and exception or pass an error message
}
// .. other actions
}
If your class cannot have a default constructor or if you don't have access to the source code for the class, you can create an adapter class that
has a default constructor
exposes those properties that need to be public
Using the Person class above with no default constructor, an adapter could look like
public class PersonAdapter {
public Person personAdaptee;
public string Name {
get { return personAdaptee.Name; }
set { personAdaptee.Name = value }
}
public string Phone {
get { return personModel.Phone; }
set { personModel.Phone = value; }
}
public string[] Pets {
get { return personAdaptee.Pets; }
set {personAdaptee.Pets = value }
}
public PersonAdapter() {
personAdaptee = new Person("", "", null);
}
}
Now let ASP.NET MVC 4 do the rest
public class PersonController : ApiController
{
// .. other actions
public HttpResponseMessage PostPerson(PersonAdapter person)
{
if ( null != person)
// CELEBRATE by doing something with your object
else
// BE SAD and throw and exception or pass an error message
}
// .. other actions
}
Try this:
$.ajax({
type: "POST",
url: "/api/slide",
data: { Title: "fghfdhgfdgfd" }
});
It is the quotes around the data attribute which are causing this:
i.e >> data: { Title: "fghfdhgfdgfd" }
not >> data: '{ Title: "fghfdhgfdgfd" }'
UPDATE:
Also your controller seems a little strange, although it is hard to tell without seeing your routing, etc.
I would expect to see something more like this:
public class SlideController : ApiController
{
public HttpResponseMessage PostSlide(string Title)
{
// Do your insert slide stuff here....
string uri = Url.Link("DefaultApi", new { id = item.Id });
response.Headers.Location = new Uri(uri);
return response;
}
}
Clearly, you will also need to update the URL in your jQuery too.
Take a look here:
http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
ANOTHER UPDATE:
It would be usual to create a CLR object to match your Json and use the MVC model binder to bind directly to that. If you don't want to do that you can bind to an object and deserialize into a Dictionary:
// POST api/values
public void Post(object json)
{
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json.ToString());
var x = values["Title"];
}
Cast the action parameter to FromBody i.e:
public class SlideController : ApiController
{
// POST /api/Slide
public void Post([FromBody]string Title)
{
}
}
$.ajax({
type: 'POST',
url: '/api/slide',
cache: false,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ title: "fghfdhgfdgfd" }),
success: function() {
...
}
});
Controller is
public class SlideController : ApiController
{
// POST /api/Slide
public void Post(string Title)
{
}
Your url is not valid, url must address the action Post in Slide controller
edit your url to url:"~/ControllerName/ActionName" in this context must be Url:"~/Slide/Post"

JSON Posting to Spring-MVC, Spring is not seeing the data

I am working on a project that the project is going to use Ajax to post JSON object to Springs-MVC. I been making a number of changes and I got it to the point where I dont get any more errors BUT I dont see the data that is getting POSTed to Spring in the object I need it in.
Here is my Spring Controller.
#RequestMapping(value="/AddUser.htm",method=RequestMethod.POST)
public #ResponseBody JsonResponse addUser(#ModelAttribute(value="user") User user, BindingResult result ){
JsonResponse res = new JsonResponse();
if(!result.hasErrors()){
res.setStatus("SUCCESS");
res.setResult(userList);
}else{
res.setStatus("FAIL");
res.setResult(result.getAllErrors());
}
return res;
}
I put a breakpoint in and my USER object never gets the data. next is a copy of my USER object:
public class User {
private String name = null;
private String education = null;
private List<String> nameList = null;
private List<String> educationList = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEducation() {
return education;
}
public void setEducation(String education) {
this.education = education;
}
public List<String> getNameList() {
return nameList;
}
public void setNameList(List<String> nameList) {
this.nameList = nameList;
}
public List<String> getEducationList() {
return educationList;
}
public void setEducationList(List<String> educationList) {
this.educationList = educationList;
}
and now for the javascript code that does the Ajax, JSON post:
function doAjaxPost() {
var inData = {};
inData.nameList = ['kurt','johnathan'];
inData.educationList = ['GSM','HardKnocks'];
htmlStr = JSON.stringify(inData);
alert(".ajax:" + htmlStr);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: contexPath + "/AddUser.htm",
data: inData,
dataType: "json",
error: function(data){
alert("fail");
},
success: function(data){
alert("success");
}
});
};
Please let me now if you can help?? I have to get this working ASAP... thanks
You also need to specify the header in your RequestMapping annotion found in your controller.
#RequestMapping(headers ={"Accept=application/json"}, value="/AddUser.htm", method=RequestMethod.POST)
Also, remove .htm in your URL path. htm is some kind of request type overide. Using .htm specifies the web server to handle the request as a classic html request. Using .json would specify to the webserver that the request expects to be handled as a json request.

Spring 3 MVC - Advanced Data Binding - Form Request with List of Simple Objects

I've read through all of the Spring 3 Web docs: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/spring-web.html but have been completely unable to find any interesting documentation on binding more complicated request data, for example, let's say I use jQuery to post to a controller like so:
$.ajax({
url: 'controllerMethod',
type: "POST",
data : {
people : [
{
name:"dave",
age:"15"
} ,
{
name:"pete",
age:"12"
} ,
{
name:"steve",
age:"24"
} ]
},
success: function(data) {
alert('done');
}
});
How can I accept that through the controller? Preferably without having to create a custom object, I'd rather just be able to use simple data-types, however if I need custom objects to make things simpler, I'm fine with that too.
To get you started:
#RequestMapping("/controllerMethod", method=RequestMethod.POST)
public String doSomething() {
System.out.println( wantToSeeListOfPeople );
}
Don't worry about the response for this question, all I care about is handling the request, I know how to deal with the responses.
EDIT:
I've got more sample code, but I can't get it to work, what am I missing here?
select javascript:
var person = new Object();
person.name = "john smith";
person.age = 27;
var jsonPerson = JSON.stringify(person);
$.ajax({
url: "test/serialize",
type : "POST",
processData: false,
contentType : 'application/json',
data: jsonPerson,
success: function(data) {
alert('success with data : ' + data);
},
error : function(data) {
alert('an error occurred : ' + data);
}
});
controller method:
public static class Person {
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
String name;
Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#RequestMapping(value = "/serialize")
#ResponseBody
public String doSerialize(#RequestBody Person body) {
System.out.println("body : " + body);
return body.toString();
}
this renders the following exception:
org.springframework.web.HttpMediaTypeNotSupportedException:
Content type 'application/json' not
supported
If the doSerialize() method takes a String as opposed to a Person, the request is successful, but the String is empty
Your jQuery ajax call produces the following application/x-www-form-urlencoded request body (in %-decoded form):
people[0][name]=dave&people[0][age]=15&people[1][name]=pete&people[1][age]=12&people[2][name]=steve&people[2][age]=24
Spring MVC can bind properties indexed with numbers to Lists and properties indexed with strings to Maps. You need the custom object here because #RequestParam doesn't support complex types. So, you have:
public class People {
private List<HashMap<String, String>> people;
... getters, setters ...
}
#RequestMapping("/controllerMethod", method=RequestMethod.POST)
public String doSomething(People people) {
...
}
You can also serialize data into JSON before sending them and then use a #RequestBody, as Bozho suggests. You may find an example of this approach in the mvc-showcase sample.
if you have <mvc:annotation-driven> enabled then:
#RequestMapping("/controllerMethod", method=RequestMethod.POST)
public String doSomething(#RequestBody List<Person> people) {
System.out.println( wantToSeeListOfPeople );
}
(List<Person> might not be the structure you would like to obtain, it's just an example here)
You can try setting the Content-Type of $.ajax to be application/json, if it doesn't work immediately.
Have a look at Jackson's spring integration. It is incredible easy to use and powerful.
A question/answer on SO that can help guide on this:
Spring 3.0 making JSON response using jackson message converter

Resources