This is my .Net Wcf WebService Service1.cs
[DataContract]
public class CompositeType
{
string degree;
string Stre;
string YearOfPass;
string Institute;
string StatusMessage;
string CheckStatus;
[DataMember]
public string deg
{
get { return degree; }
set { degree = value; }
}
[DataMember]
public string stream
{
get
{ return Stre; }
set
{ Stre = value; }
}
[DataMember]
public string yop
{
get
{ return YearOfPass; }
set
{ YearOfPass = value; }
}
[DataMember]
public string inst
{
get
{ return Institute; }
set
{ Institute = value; }
}
[DataMember]
public string StatusMsg
{
get
{ return StatusMessage;}
set
{ StatusMessage = value; }
}
[DataMember]
public string check
{
get
{ return CheckStatus; }
set
{ CheckStatus = value; }
}
}
Here, in Wcf, variables and methods are created. I used AngularJS GET method to call this Wcf Service. The output is Perfect. But using POST method in AngularJS, I get: StatusMsg= "Request object is nullTestCORS_1101.CompositeType"
Here is the AngularJS code:
var app = angular.module('starter', []);
app.controller('customerCtrl',function($scope,$http){
var Composite={"deg":"s","stream":"m","inst":"t","yop":"w"};
console.log(Composite);
$http({
url:'http://192.168.1.50/TestSubCors/Service1.svc/GetDataUsingDataContract',
method: 'POST',
data:Composite,
headers:{'Content-Type':'application/json;charset=utf-8'}
}).then(function(response){
var parsed_data = angular.toJson(response);
console.log("Success")
console.log(parsed_data);
$scope.events=parsed_data;
}),function(response){
$log.error('failure loading', errorresponse);
}
});
Why I am getting this null request object?
Related
I have popup form in my html that looks like this:
<dialog id="favDialog">
<div id="feedback"></div>
<form id="add_watchlist_symbol_form">
<label for="symbol">Enter Symbol:</label>
<input type="text" class="form-control" id="symbol" placeholder="SYMB"/><br><br>
<button type="submit" class="btn btn-default" id="add-watchlist-symbol-btn">Add</button>
</form>
<button id="cancelBtn" value="cancel">Cancel</button>
</dialog>
The dialog pops up successfully when I click a button.
The dialog contains a button called Add. It's click event is handled by javascript which sends an ajax POST request containing the form field values to Spring Boot like this:
function submit_watchlist_symbol() {
console.log("Im in submit_watchlist_symbol");
var formData = {
symbol: $("#symbol").val(),
name: "My Portfolio"
}
//$("#btn-search").prop("disabled", true);
$.ajax({
type: "POST",
contentType: "application/json",
url: "/api/v1/AddSymbolToWatchlist",
data: JSON.stringify(formData),
dataType: 'json',
success: function (result) {
if(result.status=="Done") {
$('#feedback').html(result.data.symbol +" added.");
}
else {
$('#feedback').html("<strong>Error</strong>");
}
console.log("ERROR: ",e);
},
error: function (e) {
alert("Error!")
console.log("ERROR: ",e);
}
});
// Reset FormData after Posting
resetData();
}
When I click that button I get Spring Boot error:
Resolved
[org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error: null; nested exception is
com.fasterxml.jackson.databind.JsonMappingException: N/A at [Source:
(PushbackInputStream); line: 1, column: 11] (through reference chain:
net.tekknow.moneymachine.model.Watchlist["symbol"])]
I suspect the form data is not being mapped correctly to the Watchlist.java model due to the model containing a composite key, like this:
#Entity
#Table(name = "watchlist")
public class Watchlist {
#EmbeddedId
public WatchlistId watchlistId;
public String getSymbol() {
return watchlistId.getSymbol();
}
public void setSymbol(String symbol) {
watchlistId.setSymbol(symbol);
}
public String getName() {
return watchlistId.getName();
}
public void setName(String watchlistName) {
watchlistId.setName(watchlistName);
}
public String toString() {
return "watchlist:symbol=" +getSymbol() +", name="+getName();
}
}
where watchlistId contains the symbol and name, like this:
#Embeddable
public class WatchlistId implements Serializable {
#Column(name="symbol")
private String symbol;
#Column(name="name")
private String name;
WatchlistId() {
}
WatchlistId(String symbol, String name) {
this.symbol = symbol;
this.name = name;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WatchlistId that = (WatchlistId) o;
return Objects.equals(symbol, that.symbol) && Objects.equals(name, that.name);
}
#Override
public int hashCode() {
return Objects.hash(symbol, name);
}
}
Here is the Spring Boot controller that handles the request:
#PostMapping("/AddSymbolToWatchlist")
#ResponseBody
public AddWatchlistSymbolResponse addSymbolToWatchlist(#RequestBody Watchlist watchlist){
System.out.println("made it to AddWatchlistSymbolResponse");
// Create Response Object
AddWatchlistSymbolResponse response = new AddWatchlistSymbolResponse("Done", watchlist);
return response;
}
The AddWatchlistSymbolResponse class looks like this:
public class AddWatchlistSymbolResponse {
private String status;
private Object data;
public AddWatchlistSymbolResponse(){
}
public AddWatchlistSymbolResponse(String status, Object data){
this.status = status;
this.data = data;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
Suggestions?
I figured it out. I changed the controller to this:
#PostMapping(value = "/AddSymbolToWatchlist")
#ResponseBody
public WatchlistIdResponse addSymbolToWatchlist(#RequestBody WatchlistId watchlistId){
System.out.println("made it to AddWatchlistSymbolResponse");
watchlistService.addSymbolToWatchlist(watchlistId);
// Create Response Object
WatchlistIdResponse response = new WatchlistIdResponse("Done", watchlistId);
return response;
}
And created a separate response for WatchlistId called WatchlistIdResponse.java:
package net.tekknow.moneymachine.model;
public class WatchlistIdResponse {
private String status;
private Object data;
public WatchlistIdResponse() {
}
public WatchlistIdResponse(String status, Object data) {
this.status = status;
this.data = data;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
The reason is that the Watchlist class contains only the WatchlistId property. WatchlistId contains the symbol and name properties that make up the composite index.
I have this controller function in WebAPI:
public class EntityController : APIController
{
[Route("Get")]
public HttpResponseMessage Get([FromUri]Dictionary<string, string> dic)
{ ... }
}
and my request, in javascript, looks like this:
{
"key1": "val1",
"key2": "val2",
"key3": "val3"
},
but the parse failed. is there a way to make this work without writing to much code? Thanks
my full request:
http://localhost/Exc/Get?dic={"key1":"val1"}
You could use a custom model binder:
public class DicModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(Dictionary<string, string>))
{
return false;
}
var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (val == null)
{
return false;
}
string key = val.RawValue as string;
if (key == null)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Wrong value type");
return false;
}
string errorMessage;
try
{
var jsonObj = JObject.Parse(key);
bindingContext.Model = jsonObj.ToObject<Dictionary<string, string>>();
return true;
}
catch (JsonException e)
{
errorMessage = e.Message;
}
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Cannot convert value: " + errorMessage);
return false;
}
}
And then use it:
public class EntityController : APIController
{
[Route("Get")]
public HttpResponseMessage Get([ModelBinder(typeof(DicModelBinder))]Dictionary<string, string> dic)
{ ... }
}
In the ModelBinder I used the Newtonsoft.Json library to parse the input string, then converted it to Dictionary. You could implement a different parsing logic.
See here ... with some adaptations to make. I think your difficulties are in how to call the URL.
Complex type is getting null in a ApiController parameter
i'm in trouble with this problem.
I've a Javascript structur like this:
$scope.setting= {
enabled: false,
host:"",
port:"",
user:"",
pwd:"",
path:"/",
filePrefix:"",
type:"",
sendInterval:"",
dataPeriod:"",
compression:false,
subscription:[]
};
In the controller i modify the subscription array, but when i pass it to the java code:
$http.post('/api/testAndSetFTPSetting', $scope.setting)
.success(function (data) {
console.log(data);
})
.error(function (data, status, header, config) {
});
the subscription array is null.
Here the API
#RequestMapping(value = {"/api/testAndSetFTPSetting"}, method={RequestMethod.POST})
#ResponseBody
public boolean testAndSetFTPSetting(FTPConfiguration ftp) throws JAXBException {
System.out.println(ftp.getSubscribtion().size()); // here i've ever 0 and ftp.getSubscribtion() return me null
return true;
}
Here the Java Class who controls the object:
#XmlRootElement(name="FTPconfiguration")
#XmlAccessorType (XmlAccessType.FIELD)
public class FTPConfiguration{
boolean enabled = false;
String host="127.0.0.1";
int port=22;
String user="root";
String pwd="";
String path="/";
String filePrefix="data";
FTPType type=FTPType.SFTP;
int sendInterval=15;
int dataPeriod=5;
boolean compression=false;
#XmlElementWrapper(name="subscriptions")
List<String> subscription = new LinkedList<String>();
public FTPConfiguration() {
}
public FTPConfiguration(boolean enabled,String host, int port, String user, String pwd, String path, String filePrefix,
FTPType type, int sendInterval, int dataPeriod, boolean compression, List<String> subscription) {
super();
this.host = host;
this.port = port;
this.user = user;
this.pwd = pwd;
this.path = path;
this.filePrefix = filePrefix;
this.type = type;
this.sendInterval = sendInterval;
this.dataPeriod = dataPeriod;
this.compression = compression;
if(subscription != null)
this.subscription.addAll(subscription);
}
// setter and getter method
Where is my fault?
Finally solved!!! The problem was that the javascript array in java is a comma separated String. For this the value that i received was null!
EX
JavaScript OBJ
var arr = ["1", "2", "3"];
$http.post('someUrl', arr)...
Java
#RequestMapping(value = {"/someUrl"}, method={RequestMethod.POST})
public void foo(String s) { // s will be = "1,2,3"
}
I'm newbie in Angularjs,The following Spring controller get object from database I want to print this object attributes in angularjs controller but I get undefined
#RequestMapping(value = "/rest/getById",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#RolesAllowed(AuthoritiesConstants.ADMIN)
public ChartConfigs findOne(Integer id) {
return chartConfigService.getOne(1);
}
This is Angularjs service
myappApp.factory('ChartConfigService', function ($http) {
return {
findOne: function() {
var promise = $http.get('app/rest/chartConfigs/getById').then(function (response) {
return response.data;
});
return promise;
}
}
});
This is Angularjs controller
myappApp.controller('ChartConfigController', function ($scope, ChartConfigService) {
$scope.message = ChartConfigService.findOne();
var obj=ChartConfigService.findOne();
console.log(obj.type);
});
chartconfig domain
package com.innvo.domain;
#Entity
#Table(name = "T_CHART_CONFIGS")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ChartConfigs {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
private Integer id;
#Column(name = "category")
private String category;
#Column(name = "type")
private String type;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
In your case obj will be a promise too so you have to do it like:
ChartConfigService.findOne().then(function(obj) {
console.log(obj.type);
});
obj.type is undefined because type does not exist on the promise object.
I have some JS which is passing (or trying to pass) a model and a string to an MVC controller.
The JS code is:
$.ajax({
url: self.ajaxValidationUrl,
type: "POST",
data: { model: $("form").serialize(), stepList: thisStepList },
async: false,
success: function(errors) {
console.log("Errors...");
if (errors.length > 0) {
anyServerError = true;
}
for (var i = 0; i < errors.length; i++) {
console.log(errors[i].ErrorMessage);
self.errorList += "<li>" + errors[i].ErrorMessage + "</li>";
}
}
});
The Controller looks like this:
[HttpPost]
public ActionResult ValidateReport(MyTemplate model, string stepList)
{
var errors = model.Validate();
return Json(errors);
}
The model parameter is blank and isn't resolving to the MyTemplate object. The post parameters are coming in ok.
I have a JSONmodel binder I got from somewhere, the place has escaped me but look at this.
public class FromJsonAttribute : CustomModelBinderAttribute
{
private readonly static JavaScriptSerializer serializer = new JavaScriptSerializer();
public override IModelBinder GetBinder()
{
return new JsonModelBinder();
}
private class JsonModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
if (string.IsNullOrEmpty(stringified))
return null;
return serializer.Deserialize(stringified, bindingContext.ModelType);
}
}
}
That allows you to do this in your controller.
[HttpPost]
public ActionResult GiftsCOG([FromJson] List<GiftModel> gifts, [FromJson] string guid)
{
}
This allows you to pass JSON from javascript.