how to Receive two ajax json Data from .net - javascript

i use .net and send js(ajax) two data to .net controller
in data test1 and test2 is json data.
.ajax({
type: 'POST',
url: "/test/test_Put/",
contentType: 'application/json; charset=utf-8',
data: {json_1:JSON.stringify(test1), json_2:JSON.stringify(test2)},
dataType:'JSON',
success:function(data){
},
error: function (data) {
}
});
.net controller
[HttpPost]
public JsonResult test_Put([FromBody]test1 tt1, [FromBody]test2 tt2){
}
but i saw error ㅜㅜ
how should i handle it in .net

You should only have 1 [FromBody] in your action.
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-2.1
There can be at most one parameter per action decorated with
[FromBody]. The ASP.NET Core MVC run-time delegates the responsibility
of reading the request stream to the formatter. Once the request
stream is read for a parameter, it's generally not possible to read
the request stream again for binding other [FromBody] parameters.
Create a wrapper class for this instead.
public class TestRequest
{
public test1 json_1;
public test2 json_2;
}
[HttpPost]
public JsonResult test_Put([FromBody]TestRequest data){}
BTW, you should use camel case in your method and variable names.

Related

AJAX/Spring MVC: JSON Object rendering in bracket notation in POST request

Why would a JSON be rendered in bracket notation when bound to a Web Request?
I have an application that makes 2 REST Controller calls in a row.
First, an address is read from a form, serialized, AJAXed to a validation endpoint, and returned to the UI/JS as a Response object payload. This part works fine.
$.ajax({
method: 'POST',
url: '/validate-shipping-address',
data: $shippingInfoForm.serialize()
}
#PostMapping(path = "/validate-shipping-address")
public RestResponse<Address> validateShippingAddress(
#ModelAttribute("shippingForm") ShippingForm shippingForm) {
return validateAddress(shippingForm.getAddress());
}
If the response is successful, that payload (the address) is sent directly into the AJAX call for the second endpoint. This request blows up with a 400 and never enters the actual method.
$.ajax({
method: 'POST',
url: '/shipping-stuff',
data: {
"shippingAddress": validationResponse.payload,
"shipDate": shipDate,
"csrfToken": csrfToken
}
}
#PostMapping(path = "/shipping-stuff")
public RestResponse<?> doShippingStuff(
#RequestParam(name = "shippingAddress") Address shippingAddress,
#RequestParam(name = "shipDate") #DateTimeFormat(pattern = "yyyy-MM-dd") Date shippingDate) {
doStuff(); // Never hit
}
After much analysis, the issue is that Spring MVC cannot deserialize the address passed as an Address object. In the request, I see that the address fields are rendered as address[city], address[state], etc. instead of the standard dot notation address.city, address.state (as the first request has it). If I manually access them via the request using the bracket notation as the param name, it will pull out the value. e.g. request.getParameter("address[city]");.
When I use Chrome dev tools debugger to inspect the response from the first and the object entering the second AJAX call, they look like valid JSON. The Network:Form Data section in Chrome differs though - It shows the dot notation for the first, successful call and the bracket notation for the second, unsuccessful call.
Form Data (first call):
address.firstName=John&address.lastName=Doe&address.addressLine1=123+Main+St&address.city=New+York+City&address.state=NY&address.postalCode=12345&csrfToken=XXXX
Form Data (second call): (%5B = '[' and %5D = ']')
shippingAddress%5BfirstName%5D=John&shippingAddress%5BlastName%5D=Doe&shippingAddress%5BaddressLine1%5D=123+MAIN+ST&shippingAddress%5Bcity%5D=New+York+City&shippingAddress%5Bstate%5D=NY&shippingAddress%5BpostalCode%5D=12345&shippingAddress%5BzipFour%5D=6789&shipDate=2019-05-25&csrfToken=XXXX
So there really are 2 sub-questions:
(1) Is there something in the JS handling that would cause the address to be passed in the bracket form instead of the normal JSON form? I'd think if I could get around this then Spring MVC should work like normal.
(2) Is there a way to make Spring MVC able to handle this without resorting to JSON.stringify and then parsing with Gson/ObjectMapper directly in the controller code?
I've tried all permutations I can think of involving custom wrapper objects, JSON.stringify, #RequestParam, #ModelAttribute, and bare (no annotations). I also tried stringify-ing the whole AJAX payload and using #RequestBody on a wrapper object in the controller, but then the call fails as the csrfToken is not detected.
I've read through this, this, and this, which informed the attempts above.
For now, I've worked around the issue with JSON.stringify and Gson (option 2 above), but would rather make Spring MVC do the work automatically.
Work around:
$.ajax({
method: 'POST',
url: '/commercial-checkout/shipping-stuff',
data: {
"shippingAddress": JSON.stringify(shippingAddress),
"shipDate": shipDate,
"csrfToken": csrfToken
}
});
#PostMapping(path = "/shipping-stuff")
public RestResponse<?> doShippingStuff( //
#RequestParam(name = "shippingAddress") String shippingAddressJson,
#RequestParam(name = "shipDate") #DateTimeFormat(pattern = "yyyy-MM-dd") Date shipDate) {
Address address = gson.fromJson(shippingAddressJson, AddressImpl.class);
}
As per your comment,
I also tried stringify-ing the whole AJAX payload and using
#RequestBody on a wrapper object in the controller, but then the call
fails as the csrfToken is not detected.
When you use #RequestBody you need to create corresponding POJO object to deserialise your JSON. Also you need to add content-type property in your AJAX to indicate the server that you are sending an JSON.
$.ajax({
method: 'POST',
data: 'json',
content-type: 'application/json',
url: '/commercial-checkout/shipping-stuff',
data: {
"shippingAddress": JSON.stringify(shippingAddress),
"shipDate": shipDate,
"csrfToken": csrfToken
}
});
Add a POJO as I mentioned,
public class AddressPOJO {
shippingAddress,
shipDate,
csrfToken
//getter / setters
}
Modify your controller method,
#PostMapping(path = "/shipping-stuff", consumes = "application/json")
public RestResponse<?> doShippingStuff( #RequestBody AddressPOJO addressPJO) {
// do your logic..
}

Angular JS Post is not working

I am using angularjs and ionic.I post multiple data from angular js to Api Controller in asp.net mvc
I have below code in order to post multiple form data to controller in asp.net mvc from angularjs.
$http({
method: 'POST',
url: 'http://localhost:51425/api/values/Response',
params: { PropertyFirst: "1", PropertySecond: "2" },
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
}).success(function (data) {
alert("ok");
});
If i use below code this works
[HttpPost]
public object Response(string PropertyFirst , string PropertySecond)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
return null;
}
However, if i use below code it is not working
PropertyClass
public string PropertyFirst{ get; set; }
public string PropertySecond{ get; set; }
Controller side
[HttpPost]
public object Response(PropertyClass propertyValues)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
return null;
}
I get below error :
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
Question:
How can i post PropertyFirst and PropertySecond to PropertyClass ?
Any help will be appreciated.
Thanks.
From the Angular $HTTP docs :
params – {Object.} – Map of strings or objects which will be serialized with the paramSerializer and appended as GET parameters.
I don't know much about asp MVC framework, but if you change the 'params' key to a 'data' key, your request will be correct.
Unfortunately I can't really help with the ASP controllers, as I am entirely unfamiliar with that language.

How can I get a Spring #RestController to accept parameters in JSON format rather than www-form-urlencoded?

Using Spring 4.1.7 on JDK 1.8, I have an #RestController class that looks like this:
#RestController
public class ServiceAController {
public static final Logger LOG = Logger.getLogger(ServiceAController.class);
#RequestMapping(value="/rest/servicea", method=RequestMethod.POST)
public ServiceAResponse serviceA(#RequestParam(value="parmA", defaultValue="defaultParmA") String parmA,
#RequestParam(value="parmB", defaultValue="defaultParmB") String parmB,
#RequestParam(value="parmC", defaultValue="defaulParmC") String parmC) {
LOG.info("Inside Service A handler: " + parmA + " B: "+ parmB + " C: "+ parmC);
}
When I send a POST to /rest/servicea from a javascript like this, everything works, and I see the values "a", "b", and "c" printed in my log:
var data = {
"parmA": "a",
"parmB": "b",
"parmC": "c"
}
$.ajax({
type: "POST",
url: "./rest/servicea",
contentType: "application/x-www-form-urlencoded",
data: data,
dataType: "json",
success: submitAuthSuccess,
error: submitAuthFailure
})
However, when I try to change the call from the javascript to this (to change the protocol to REST rather than www-urlencode), I get the default values (defaultParmA, defaultParmB, defaultParmC) in my log:
var data = {
"parmA": "a",
"parmB": "b",
"parmC": "c"
}
$.ajax({
type: "POST",
url: "./rest/servicea",
contentType: "application/json",
data: JSON.stringify(data),
dataType: "json",
success: submitAuthSuccess,
error: submitAuthFailure
})
I think I'm missing something in the #RestController class to get it to parse the JSON rather than expecting www-urlencoded data.
I tried changing the #RequestMapping annotation on the serviceA method to add the consumes="application/json" attribute, but that had no effect.
What can I change to make this work, using JSON rather than urlencoded data in the POST body?
The #RequestParam javadoc states
Annotation which indicates that a method parameter should be bound to
a web request parameter.
This is retrieved through the various ServletRequest methods for request parameters. For example, ServletRequest#getParameterMap() which states
Request parameters are extra information sent with the request. For
HTTP servlets, parameters are contained in the query string or posted
form data.
In your second snippet, you aren't sending either. You're sending JSON in the request body.
Spring has a mechanism (it has many, and custom ones) for deserializing that into the data you expect. The standard solution is #RequestBody, assuming you have an appropriately registered HttpMessageConverter that can handle the JSON. Spring automatically registers MappingJackson2HttpMessageConverter if you have Jackson 2 on the classpath, which can correctly deserialize JSON into Java POJO types.
The documentation gives a number of examples and explains how you would use it. With JSON, you could define a POJO type with fields that correspond to the ones you send
class RequestPojo {
private String paramA;
private String paramB;
private String paramC;
// and corresponding getters and setters
}
and add a #RequestBody annotated parameter of this type to your handler method
public ServiceAResponse serviceA(#RequestBody RequestPojo pojo) {
pojo.getParamB(); // do something
return ...;
}
Jackson lets you define, through annotations or through configuration of the ObjectMapper, how to deal with absent values.
#RestController is not involved here. As its javadoc states,
Types that carry this annotation are treated as controllers where
#RequestMapping methods assume #ResponseBody semantics by default.
It looks to me like you are passing a single JSON object at this point, rather than a set of parameters, hence Spring cannot match what you're sending to any of the parameters you've provided.
Try
#RequestBody List<ListUnit> listOfUnits
instead of #RequestParam

Get json datas from C# to javascript without using [WebMethod]

I have a C# Project, and a ASP.NET project (without database).
I want to call some methods from my C# Project, get the results in JSON and use it in my javascript without using the [WebMethod], I tried to make a Controller but I'm a little bit lost.
If you have any tips it would be nice, thank you.
The code in the controller should look like:
public class HomeController : Controller
{
[...]
public virtual ActionResult GetExample()
{
[...]
var result = ...;
return Json(result, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public virtual ActionResult Update(MyModel model)
{
[...]
var result = model
return Json(result);
}
[...]
}
And from your java script file you make an ajax call:
$.ajax({
url: "<path>/Home/GetExample",
type: "GET",
dataType: "json",
cache: false,
success: function (html) {
[...]
}
})
or:
$.ajax({
url: "<path>/Home/Update",
type: "POST",
dataType: "json",
data: $(#my-form).serialize(),
cache: false,
success: function (html) {
[...]
}
})
I don't have enough reputation so adding my comments here. You probably want to use Web Api here which is the reason you created controller. You probably need to refer Web Api site which will help you build controllers and expose interface to be called from javascript.
Web API

ASP.NET MVC 4 FormCollection is Empty using Angularjs $Http.post

I’m submitting a form post using Angularjs (1.2.20) to Microsoft ASP.Net MVC 4:
public ActionResult Save2(FormCollection customer)
{
//TODO: Do some stuffs...
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
However, the FormCollection is empty. I know that the data is being sent because if I change it to the following code below (using strongly type CustomerVm), it works as expected.
public ActionResult Save1(CustomerVm customer)
{
//TODO: Do some stuffs...
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
I’m using FormCollection so that I can add ASP.Net anti-forgery token in the data (instead of headers). Below is my custom javascript code. Also you can find the entire code (Visual Studio) here
You need to send the request with a content-type of application/x-www-form-urlencoded and encode the request body as such. This is a good start but it's sending the data as JSON.
var data = JSON.stringify(customer);
// FormCollection
$http({
method: 'POST',
url: '/Home/Save2',
//dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset-UTF-8',
//contentType: 'application/json; charset-UTF-8',
data: data
});
Turning the object into a URL encoded form is actually pretty complex. Thankfully, Ben Nadel has already created a transformRequestAsFormPost service to do this via a request transformer. You can give it a try by adding in his code and making this change to yours...
myApp.factory('customerSvc', function ($http, transformRequestAsFormPost) {
return {
// ...
save2: function (customer, antiForgeryToken) {
$http({
method: 'POST',
url: '/Home/Save2',
transformRequest: transformRequestAsFormPost,
data: data
});
}
};
});

Categories