I've been looking for answers for the past days and still I haven't got any idea on how can I make my app work. I only have one controller for all the subtabs of my app. I had one http get method for one subtab under the main controller and I need another http get method for another subtab to also be under the main controller. How can I possibly do that?
You can use attribute routing.
[HttpGet]
[Route("method1/{id}")]
public HttpResponseMessage index(string id)
{
try
{
// your code
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.Forbidden,ex.Message);
}
}
[HttpGet]
[Route("method2/{Id}")]
public HttpResponseMessage GetData(string GetRecordsById)
{
try
{
//your code
}
catch (Exception)
{
throw;
}
}
Related
I have a GET Web API method in another controller working fine with UseCors allowing any origin enabled in Startup.cs
When I try to call a POST method I get a No 'Access-Control-Allow-Origin' header is present error returned along with a 500 error.
What am I doing wrong?
using System.Collections.Generic;
using CrossSell.Business.Exceptions;
using CrossSell.Business.Interfaces;
using CrossSell.Entities;
using Microsoft.AspNetCore.Mvc;
namespace CrossSell.API.Controllers
{
[Produces("application/json")]
[Route("api/Product")]
public class ProductController : Controller
{
private readonly IProductManager productManager;
public ProductController(IProductManager productManager)
{
this.productManager = productManager;
}
// POST: api/Product
[HttpPost]
public IEnumerable<Opportunity> Post([FromBody]ClientIdentifiable[] clients)
{
try
{
return productManager.GetCrossSellOpportunities(clients);
}
catch (NoInForceOrHistoricalPoliciesException)
{
return new[] { new Opportunity(true, "No In Force or historical policies") };
}
}
}
}
I'm calling the Post method from my React app (which runs on localhost:3000):
getDashboardData() {
var self = this;
axios.post( 'http://localhost:5000/product/api/', this.state.clientIdentifiables).then(function (response) {
console.log(response);
});
}
I forgot to add the dependency injection entry in ConfigureServices method of Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddTransient<IClientManager, ClientManager>();
services.AddTransient<IClientRepository, ClientRepository>();
// added the following and it hit the web api method correctly
services.AddTransient<IProductManager, ProductManager>();
services.AddTransient<IProductRepository, ProductRepository>();
}
So I'm having a little trouble when updating a resource in Grails. So here is my controller, in which I'm overriding some methods
#Override
protected saveResource(resource) {
if (request.post) {
permissionsService.addPermission(resource.id, springSecurityService.getCurrentUser(), 'Outing')
}
resource.save(flush: true)
}
#Override
protected updateResource(resource) {
if (permissionsService.isAdmin()) {
println 'doesnt print'
saveResource(resource)
} else if (permissionsService.canWrite('Outing', params.id, springSecurityService.getCurrentUser())) {
println 'doesnt print'
saveResource(resource)
} else {
println 'prints to console'
response.status = 404
}
}
This is what the top of the controller looks like
import grails.converters.JSON
import grails.rest.*
class OutingController extends RestfulController {
static responseFormats = ['json']
OutingController() {
super(Outing)
}
...............
}
My problem is that when I perform a PUT, for some reason the resource is still updated and saved. I can't figure out why because it never hits the saveResource or any other save function to my knowledge. I would like it to return with the status 404, but I could use some help with that. I'm basically adding permissions to the restful controller. Thanks for any help
Here is the RestfulController if you'd like to look. https://github.com/grails/grails-core/blob/master/grails-plugin-rest/src/main/groovy/grails/rest/RestfulController.groovy
I am making the following PUT request using AJAX to a RESTful web service. Before making the request, I convert the data returned from form submission (using ng-submit) to a JSON String:
var serializedData =angular.toJson(person);
I then send it as data in an AJAX call like this:
$http({
method: 'PUT',
url: myurl +person.personID,
data: serializedData,
headers: {
'Content-Type': 'application/json'
}
}).success(function(data) {
console.log("Success");
});
Now in my web service, I want to get this data and create a Java object:
#PUT
#Path("/person/{id}")
#Produces({ MediaType.APPLICATION_JSON })
#Consumes({MediaType.APPLICATION_JSON})
public Response updatePerson(#PathParam("id") String personID,
#Context HttpServletRequest httpRequest) {
Response.ResponseBuilder builder = Response.ok();
Person person =null;
String data =null;
BufferedReader reader =null;
StringBuffer buffer = new StringBuffer();
try
{
reader = new BufferedReader(new InputStreamReader(httpRequest.getInputStream()));
}
catch (IOException e1)
{
e1.printStackTrace();
e1.getCause().toString();
}
try
{
while((data =reader.readLine()) != null){
buffer.append(data);
}
}
catch (IOException e1)
{
e1.printStackTrace();
}
String bufferToString =buffer.toString();
try
{
person =JSONUtil.toObject(bufferToString, new TypeReference<Person>() {});
}
catch (JsonParseException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
catch (JsonMappingException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (person == null) {
builder = Response
.status(Response.Status.NOT_FOUND.getStatusCode());
return builder.build();
}
try {
deviceService.update(dev);
JSONUtil.toJSONString(dev);
builder.entity(JSONUtil.toJSONString(dev));
} catch (JsonGenerationException e) {
} catch (JsonMappingException e) {
} catch (IOException e) {
return builder.build();
}
Here is a problem I cant seem to figure out. When the ajax call is made, data does reach to the web service, which means it is a JSON string because that is what angular.toJson does [https://docs.angularjs.org/api/ng/function/angular.toJson]. After reading it with the reader and converting it to a string and passing it to the JSONUtil.toObject(bufferToString, new TypeReference<Person>() {});, it gives me a 404 status code, meaning the person object is null. Now here is the weird thing I dont understand. If I do a get request for a Person object in POSTMAN client, edit a value in that JSON and send it as body of application/json type in a PUT request (from POSTMAN), then it works. I have checked through JSONLint that the JSON string that I receive from AJAX is valid.. Why is this happening?? I passed a string to the JSONUtil.toObject(bufferToString, new TypeReference<Person>() {});, which is what that method needs. Is it not in the right format? I cant seem to understand. Any help will be appreciated. Have been stuck on this for 4 hours now. Thank you.
I post this as an answer since I can't comment yet. The following is a suggestion to refactor code to make it easier to mantain. If doing so is not an option, I'd suggest you post the StackTrace printed on your console to provide further assistance.
Now the suggestion:
You should try JAX-B. It'd make your code much more manageable and free you from the hazzard of doing serialization and deserialization manually. You can use all JAX-B POJOs as parameters or return types:
#POST
public StatusDTO createStatus(StatusDTO dto) {
//your code here
}
All you need to do is create a POJO and annotate it with #XmlRootElement and you can use it directly as parameter in your Jersey services.
With this you can return the POJO and JAX-B will do the serialization, so you don't have to build the response manually either. Finally, whenever you need to return an error code, try throwing a WebApplicationException.
You need other solution to work with json in Java, in Spring use Jersey and Jackson and i catch the json objects to a java pojo, check this example https://github.com/ripper2hl/angular-todo/
and the code for catch object is very simple
#RequestMapping(method = RequestMethod.POST)
public Todo saveTodo(#RequestBody Todo todo){
return todoDao.save(todo);
}
For the last few days I have been trying to implement SignalR into my AngularJS/WebAPI application.
I have been able to successfully send/receive messages from client to client, however when I push messages purely from the Server, none of the clients receive any messages.
I have seen many people having the same problem, the answer always seems to be using GlobalHost.ConnectionManager.GetHubContext which I have been implementing, without error, however the clients still don't receive any of the messages.
I thought that perhaps it's because WebAPI calls are asynchronous and and therefore takes place on a different thread, but I can't be sure. Please could someone have a look and tell me what I'm doing wrong.
This is my Hub Class:
public class ChatHub : Hub
{
public void Send(string name, string message)
{
// Call the broadcastMessage
Clients.All.broadcastMessage(name, message);
}
public void RunMe()
{
System.Diagnostics.Debug.WriteLine("Client Started");
}
public static void Notify(string name, string message)
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
hubContext.Clients.All.broadcastMessage(name, message);
}
}
This is the Angular Controller in Javascript:
$scope.chat = $.connection.chatHub;
$scope.chat.client.broadcastMessage = function (name, message) {
$scope.$apply(function () {
var scope = angular.element($('#discussion')).scope();
scope.chatMessage = message;
alert(message);
});
};
$.connection.hub.start()
.done(function ()
{
console.log('Now connected, connection ID=' + $.connection.hub.id);
$scope.chat.server.runMe();
})
.fail(function(){ console.log('Could not Connect!'); });
$('#sendmessage').click(function () {
$scope.chat.server.send("SERVER", $('#inputMessage').val());
});
This is the Controller that is trying to notify the clients from the server
public class UserController : ApiController
{
#region METHODS
[ActionName("Create")]
[HttpPost]
public HttpResponseMessage Create(JObject parameters)
{
//DYNAMIC DATA
dynamic data = parameters;
//CHECK IF CALL FAILED
if (data == null)
return Request.CreateResponse(HttpStatusCode.InternalServerError, "Request is null");
//PERFORM REQUEST
using (var svc = new UserService())
{
//SET Parameters
String Username = data.Username;
String Password = data.Password;
//NOTIFY USERS
ChatHub.Notify("SERVER", "SERVER MESSAGE");
//CREATE Response
var response = svc.Create(Username, Password);
//RESPOND
return Request.CreateResponse(HttpStatusCode.OK, response);
}
}
}
So just to reiterate, when the "sendmessage" button is clicked on my UI, it sends a message to the server which is then received again by the clients, this works 100%,
However when I call the static Notify method from the Controller None of the clients receive any messages.
Calling the function does not return any errors.
Please could someone help me!
<!--Reference the SignalR library. -->
<script src="Scripts/jquery.signalR-2.2.0.min.js"></script>
Check your jQuery.signalR version.
If you are using dependency injection, the example at ASP.NET is wrong, you have to set your GlobalHost.DependendcyResolver in the the Global.asax file. not in the startup class.
Blog - RESTful Resource Controller
route to the controller Blog
Route::resource('blog', 'BlogController');
Simple query does not work
$http.delete('/blog/1');
return
403 Forbidden
POST(store), GET (index, show), requests work
delete (destroy) does not work
$http.post('/blog/1', {_method: 'DELETE'});
return
405 Method Not Allowed
<?php
class BlogController extends \BaseController {
public function index()
{
return Blog::orderBy('id')->get();
}
public function store()
{
....
....
}
public function edit($id)
{
return Blog::find($id);
}
public function destroy($id)
{
Blog::destroy($id);
}
}
Some web servers may block http delete method.
if you use Apache, try to allow it. Add this code to your .htaccess file:
<Limit GET POST DELETE>
Allow from all
</Limit>
Similar problem was posted here
Hope this helps :)