I am using Angular 2 in order to send http requests to the server.
The server is running with ASP.Net.
My API:
public class LagerController : ApiController
{
public IHttpActionResult RepHistorie(string vnr, string lagerort)
{
...
}
}
So I would call the API with
http://123.456.7.89/api/lager?vnr=W17291092373&lagerort=0382691395
This works fine when using a tool called postman with wich you can test API's.
But when making a post request with Angular 2, it doesn't work.
It says that the HTTP-resource is not found.
Angular 2:
submit() {
var body = 'vnr=W17291092373&lagerort=0382741400';
var link = 'http://123.456.7.89/api/lager';
this.http.post(link, body)
.subscribe(data => {
console.log(data);
}, error => {
console.log("Oooops!");
});
}
It seems like the parameters aren't added correctly.
Edit: Changed tag
This needs clarification, since the API above seems to be a GET Request.
In case it is a POST Request , then you should use the whole URL while running the API
In case you want to submit an object , you should use [FromBody] as a parameter
Example
[HttpPost]
public IHttpActionResult( [FromBody]YourObject item ) {
}
====
Client-side
var postUrl = 'http://123.456.7.89/api/lager?vnr=W17291092373&lagerort=0382691395';
var postObject = {};
http.post(postUrl,postObject)
For GET request where you would like to use QueryString
[HttpGet]
public IHttpActionResult RepHistorie([FromQuery]string vnr,[FromQuery]string lagerort){
...
}
====
// Query string can be built using RequestOptionsArgs as well
var builtUrl = 'http://123.456.7.89/api/lager?vnr=W17291092373&lagerort=0382691395';
http.get(builtUrl)
Alternative way is to
var getUrl = 'http://webapi/api/lager';
var requestOptions = {};
http.get(getUrl,requestOptions);
Reference:
Angular HTTP: https://angular.io/api/http/Http , check get() and post() methods
RequestOptionsArgs : https://angular.io/api/http/RequestOptionsArgs
Related
i have a xamarin app that is trying to talk to use SignalR in Azure functions.
i have 2 azure functions as per the documentation.
public static class NegotiateFunction
{
[FunctionName("negotiate")]
public static SignalRConnectionInfo GetSignalRInfo(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
[SignalRConnectionInfo(HubName = "chat")] SignalRConnectionInfo connectionInfo)
//, UserId = "{headers.x-ms-client-principal-id}"
{
return connectionInfo;
}
}
and
public static class SendMessageFunction
{
[FunctionName("Send")]
public static Task SendMessage(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
[SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
// var chatObj = (ChatObject)(message);
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will only be sent to this user ID
// UserId = chatObj.ReciversId,
Target = "Send",
Arguments = new[] { message }
});
}
}
in my xamarin client i am connecting like this.
try
{
_connection = new HubConnectionBuilder()
.WithUrl("http://192.168.1.66:7071/api")
.Build();
_connection.On<string>("Send", (message) =>
{
AppendMessage(message);
});
await _connection.StartAsync();
}
I send message using this code in one of the pages of Xamarin app page.
try
{
await _connection.SendAsync("Send", MessageEntry.Text);
MessageEntry.Text = "";
}
connection code works it hits "negotiate" function properly but when i call SendAsync it does not hit break-point in [FunctionName("Send")] and nothing happens. It doesn't give me any exception as well.
local settings are like this
Update
i also tried Invoke. it didnt worked.
Should i try making a POST call to [FunctionName("Send")] ?
The way SignalR SaaS works in Functions is slightly different to using the NuGet package in a .NET Application.
You can't invoke a function using the SignalR library, as you can see on the attribute in your function, it's expecting a Http trigger so you have to do a POST to this endpoint instead of invoking it as you normally would.
[HttpTrigger(AuthorizationLevel.Anonymous, "post")]
You still want to listen to the Send target as normal.
when I call my API Webservice its returns an empty array.
In my Header request, i have only a jwt token for authenticating
In Angular:
getSheets(): Observable<Sheet[]> {
return this.http.get(this.config.apiUrl + '/api/SheetsRelationAPI', this.jwt())
.map(this.extractData)
.do(data => console.log('SheetsData:', data)) // debug
.catch(this.handleError);
In Asp.net MVC 5:
[HostAuthentication("bearer")]
[System.Web.Http.Authorize]
public class SheetsRelationAPIController : ApiController
{
private GSheetsContext db = new GSheetsContext();
// GET: api/SheetsRelation
[ResponseType(typeof(SheetsRelationView))]
public IQueryable<SheetsRelationView> GetSheetsRelation()
{
var claims = (User.Identity as System.Security.Claims.ClaimsIdentity).Claims;
var username = "";
foreach (var claim in claims)
if (claim.Type.ToString() == "sub")
{
username = claim.Value.ToString();
}
//var tasks = from tsk in db.SheetsRelation.Include(s => s.SheetsContent.id )
//select tsk;
var sheetsRelation = db.SheetsRelationView.Where(jt => jt.Username == username);
return sheetsRelation;
}
}
UPDATE 1:
It seems it's worked in PostMan and I have a JSON in response But in Angular, i haven't any JSON in response.
Three things you may wish to try -
Not related to this issue, but I always decorate my APIs with the specific http method, to ensure there isnt any confusion on my part - [HttpGet] in this case.
Refactor your API class so that it doesnt have direct dependencies on GSheetsContext and User.Identity (make yourself an injectable service to handle that, so that you can mock the behavior.)
Unit test the controller method with mocked dependencies, so that you can be sure that your controller is behaving as it is expected to.
Edit, if that sounds like too much work
Comment out your existing controller logic and put a stub method there that just returns something like return db.SheetsRelationView.Create()
If that works, then you know your issue is not with your API, and is in the logic. Then refer back to steps 2 & 3 above ;)
I use HttpClient with ASP to consume services in a remote database
In my ASP controller (Collaborateur), I have the following code:
public Boolean UpdateCollaborateur(Collaborateur collaborateur) {
using (var client = new HttpClient()) {
(.......)
}
return true;
}
Then in my angular service, i have the following call:
.factory('UpdateCollaborateur', function ($http) {
var fac = {};
fac.Update = function (collaborateur) {
return $http.put('/Collaborateur/UpdateCollaborateur/'+collaborateur);
};
return fac;
})
By putting a breakpoint , why i can not access in my function UpdateCollaborateur after executing my method in my controller angularjs?
Thanks for your help
I may be wrong but shouldn't it be:
return $http.put('/Collaborateur/UpdateCollaborateur/', collaborateur);
You have a + instead of a ,.
You also likely need the [HttpPut] attribute on the method.
NOTE: HTTP PUT not allowed in ASP.NET Web API
Using ASP.Net Web API service I can get the current windows user using the following.
public class UserController : ApiController
{
public string Get()
{
var id = WindowsIdentity.GetCurrent();
return id.Name;
}
}
My question is how can I find the current user logged in a angularjs controller without having to call the web api service?
myApp.controller('TestCtrl', function ($scope) {
$scope.getUserData = function(){
$http({method: 'GET', url: '/URLtoResourceInWebService'}).
success(function(data, status, headers, config) {
//use the data of your User object
}).error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
}
}); //End of Controller
Here is a real simple example of how to hit an endpoint in Angular and get back a resource from a WebService. I would actually suggest extracting out your API calls however into a service rather than using the "$http" because then you centralize them in one place, and if you switch API's your code doesn't break all over. Let me know if this helps.
I have 2 Web API Projects:
Api1 is a testing-Environment for the JavaScript Front-End, but has a API
Back-end(the default ValuesController), also for testing.
Api2 is the "true" Back-end, from which the Experimental JavaScript UI schould pull Data. For Testing, i use the default ValuesController here too, because, i want to have the same Output.
Status Quo
The Api1-UI can query the Data from the ValuesController of the own API
The Api2 returns the Correct Data(tested in Firefox and with Fiddler)
The Code
JavaScript Client:
var _load = function (url) {
$.ajax({
url: url,
method: 'GET',
accepts: "application/json; charset=utf-8",
success: function (data) {
alert("Success: " + data);
},
error: function (data) {
alert("Error :" + data);
}
});
};
WebApi Controller method:
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
Problem
The JavaScript UI of the experimental Front-End is not able to display, or even receive, the data from the API 2, which is, according to Fiddler, sent correct.
My first thought was, I am using the wrong Method, but i tried $.getJSON and $.ajax. But i always end up with an error. It just says statusText= "Error"
I don't get, why it can display Data from the own ApiController, but not from the "External"...
Thanks for any Help/Suggestions
You seem to be accessing data from X from a different domain Y using ajax. This seems to be a classic cross domain access issue.
You need to set Access-Control-Allow-Origin to value " * " in your response header.
Response.Headers.Add("Access-Control-Allow-Origin", "*")
There various ways you can solve this
defining this header in IIS
using a actionfilter attribute like below
FilterAttribute
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Response != null)
actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
base.OnActionExecuted(actionExecutedContext);
}
}
Using Attribute on Controller Action
[AllowCrossSiteJson]
public Result Get(int id)
{
//return appropriate result
}