Asp.net Web Api get request header - asp.net

I have an Api project in that I have 2 different Controllers :
one controller is a System.Web.Mvc controller:
public class HomeController : Controller
in that, I have define a request like below:
var request = System.Web.HttpContext.Current.Request;
request.Headers.Add("token", "test");
one other controller is a Api controller:
public class CalendarController : ApiController
{
private string _accessToken;
public CalendarController()
{
IEnumerable<string> accessTokenValues;
var request = System.Web.HttpContext.Current.Request;
var token = request.Headers.GetValues("token");
//var tokenValues = accessTokenValues as string[] ?? accessTokenValues.ToArray();
//_accessToken = (tokenValues.Any()) ? tokenValues.First() : "";
} }
I added "token" to the request header but I cannot get it in the Api controller. Please help me !
Thanks!

The originating caller is responsible for setting the request headers. Therefore adding your header on the first request to HomeController means that it will not be added to subsequent requests to CalendarController. Take a look at : https://msdn.microsoft.com/en-us/library/bb470252.aspx for more details about the ASP.NET request response pipeline
Ultimately, it depends on what you want to achieve as to how you might add to the header.
For example, If you have all the information on the server side to add to the request header and you're using OWIN you can add a custom middle-ware layer that will intercept incoming calls and add your custom header as the request makes its way to your controller.(http://www.asp.net/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline)

Related

How to obtain request parameter from query string or request body inside ASP.NET Web API 2 Controller

In PHP, one can access request property by using the $_REQUEST 'superglobal' variable.
In Java Servlet, one can also do something similar by calling getParameter(string) or getParameterValues(string) on the incoming HttpServletRequest instance.
Both of these method do not care if the data is conveyed on the query string or on the body. They are HTTP-method-agnostic-ways of getting request properties.
How to do the same using ASP.NET 4.x (not Core) Web API 2?
As far as possible, I do not want to use model binding or route parameter. I just want to use built in Properties of the ApiController to access the request parameter directly.
Here's what I'm trying to do:
public class MyController : ApiController
{
[HttpPost]
public IHttpActionResult Index()
{
// somehow obtain 'requestParam ' either from query string OR from request body
var requestParam = Request.???
return Ok(requestParam);
}
}

How to hide Controllers routes in ASP.NET WebApi

I have a WebApi project and I got myself in this situation. Let's say that I have a Route :
[Authorize]
[RoutePrefix("api/v1/GG")]
public class StorkUserController : ApiController
{
private IAuthenticationManager Authentication
{
get { return HttpContext.Current.GetOwinContext().Authentication; }
}
[Route("UpdateUser")]
[HttpPost]
So When I start the application, if i directly type in my browser this route :
http://localhost:52494/api/
I will get this Error with some details :
Or if I navigate to http://localhost:52494/api/v1/GG I get :
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:52494/api/v1/GG/'.","MessageDetail":"No type was found that matches the controller named 'v1'."}
How to prevent for this Happen since these routes could be easily to be found, and instead of it, show something like "ERROR 404"! Thanks!

Understanding about constructor in Web Api

My web api looks like:
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly ApplicationDbContext _context;
public ValuesController(ApplicationDbContext context)
{
_context = context;
}
[HttpGet]
public string Get()
{
// get random user
var user = _context.Users.SingleOrDefault();
return user?.Email ?? "";
}
}
Trying to call it via jquery:
$.get('/api/values', function (email) {
console.log(email)
})
I've 2 questions:
1/. Why didn't console.log(email) work although I was getting the response successful?
There was nothing in the Console tab.
2/. When I made a request to server (/api/values), the breakpoint had been caught:
My question: where had ValuesController been called within context? I'd sent a request from client, then the constructor was hit (I'm sure that I didn't send something like ApplicationDbContext from client to server :v)
UPDATE: By changing $.get('/api/values', {}, function (email) {} to $.get('/api/values', function (email) {}. I've fixed the first problem. It's my bad. Sorry about that.
Shorter Answer
My question: where had ValuesController been called within context? I'd sent a request from client, then the constructor was hit.
The HTTP Request arrived. ASP.NET MVC Routing told the application to use the ValuesController to handle the request. The application constructed the ValuesController, supplying an instance of ApplicationDbContext via dependency injection.
Longer Answer
The Startup.Configure method is used to specify how the ASP.NET application will respond to individual HTTP requests. Since you are using Web API, you have configured app.UseMvc(). Result: when an HTTP Request arrives, MVC Routing tells the application to use the appropriate controller.
The Startup.ConfigureServices method is used to specify services that are available via dependency injection. Since you are injecting an ApplicationDbContext into your constructor, you have configured services.AddDbContext<ApplicationDbContext>(). Result: when the application constructs a ValuesController, ASP.NET Dependency Injection will provide an instance of the ApplicationDbContext.

Controller invoking another controller C# WebApi

I have a controller, it needs to invoke another controller. We WERE doing this work on the client. We want to do this server side for performance reasons.
Request is a POST
Request Url = "http://example.com/api/foo/1234567 (pretty standard url with binding for an id)
Request Data
{
something1:'abc',
something2:'def',
copyFromUrl : '/api/bar/7654321'
};
The copyFromUrl could be any other controller in the application. I don't want to hand jam a bunch of if statements up and down the stack to do the binding.
Complicating the issue is most controllers have three different GET signatures.
Get(sting id)
Get(sting id, string xpath)
Get()
One way of doing this, would be to basically short-circuit HttpServer and HttpClient classes. I am using here ASP.NET Web API 2, but hopefully same technique can be used with original Web API.
Here is the minimalistic working sample:
public class BarController : ApiController
{
// GET http://localhost/api/bar
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] {"Foo Bar", "Progress Bar"};
}
// GET http://localhost/api/bar?bar=Towel Bar
[HttpGet]
public IEnumerable<string> GetCustomBar(string bar)
{
return new string[] {"Foo Bar", "Progress Bar", bar};
}
// POST http://localhost/api/bar?action=/api/bar?bar=Towel Bar
[HttpPost]
public HttpResponseMessage StartAction(string action)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
var server = new HttpServer(config);
var client = new HttpClient(server);
var response = client.GetAsync("http://localhost/" + action).Result;
return response;
}
As you can see here, the first two actions differ in parameters, the third action accepts url (as in code example) that allows it to invoke any other action.
We are basically hosting a server in memory, applying same routes our real server has, and then immediately querying it.
Hard-coded localhost is actually not used run-time, the routes ignore it, but we need valid absolute URL name for the internal validation to pass.
This code is just an illustration, proof-of-concept if you may.

Angularjs - Spring MVC integration

I am trying to integrate AngularJS with Spring MVC; but I am not able to post parameters to spring controller as RequestBody. Can some one help me to achieve the same. Below is brief flow of my program.
After doing data entry TodoNewController gets executed. From here I am calling user-defined method "create" which I have defined in services.js. As per the flow after this it should call create method of TodoController.java along with input params; but it is not happening. Can some one let me know what is wrong with the code. Below is the code for same.
controller.js
function TodoNewController($scope, $location, Todo) {
$scope.submit = function () {
Todo.create($scope.todo, function (todo) {
$location.path('/');
});
};
$scope.gotoTodoListPage = function () {
$location.path("/")
};
}
services.js
angular.module('todoService', ['ngResource']).
factory('Todo', function ($resource) {
return $resource('rest/todo/:id', {}, {
'create': {method:'PUT'}
});
});
TodoController.java
#Controller
public class TodoController {
private static final AtomicLong todoIdGenerator = new AtomicLong(0);
private static final ConcurrentSkipListMap<Long, Todo> todoRepository = new ConcurrentSkipListMap<Long, Todo>();
#RequestMapping(value = "/todo", method = RequestMethod.PUT)
#ResponseStatus(HttpStatus.NO_CONTENT)
public void create(#RequestBody Todo todo) {
long id = todoIdGenerator.incrementAndGet();
todo.setId(id);
todoRepository.put(id, todo);
}
}
Spring expects application/x-www-form-urlencoded as the Content-Type of the request. You may try inject $http into your service and invoke $http.defaults.headers.put["Content-Type"] = "application/x-www-form-urlencoded"; at the beginning of it.
Modify the request mapping to match the actual mapping /rest/todo and change the databinding to use #ModelAttribute.
#RequestMapping(value = "/rest/todo", method = RequestMethod.PUT)
#ResponseStatus(HttpStatus.NO_CONTENT)
public void create(#ModelAttribute Todo todo) {
long id = todoIdGenerator.incrementAndGet();
todo.setId(id);
todoRepository.put(id, todo);
}
Isolate the problem first. Is it Spring or Angular that's causing the issue? I suggest you install a Rest client plugin either in Chrome or FireFox. Then create a PUT request and enter the correct endpoint URL. If you're able to receive the correct response, then it means your Angular request is constructed incorrectly.
Now, run your Angular-based client. Make a PUT request. Inspect the parameters and request sent (in Chrome, you can use Developer tools) and see if it matches the request you sent earlier. If it does, then it should work. If not, then you know the problem.
Also, your Angular resource:
$resource('rest/todo/:id')
has a different URL than what you have in your Spring controller
#RequestMapping(value = "/todo", method = RequestMethod.PUT)
So the first one is like 'rest/todo/1' and the latter is '/todo'. I don't think those would match.

Resources