I want to open webSocket by web api post request.
I tryed to use HttpContext.Current.AcceptWebSocketRequest but it didn't work (as you can see in the following example) because HttpContext.Current is null in self host.
public class ChatController : ApiController
{
public HttpResponseMessage Get(string username)
{
HttpContext.Current.AcceptWebSocketRequest(new ChatWebSocketHandler(username));
return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
}
}
Is there a way to get the current http context without IIS?
Or what is the best way to open websocket?
Related
Can someone explain me the difference between Web services & web API? I have gone through so many blogs but all of them seems to be using the same bookish knowledge. What's the actual difference between them in real terms?
As #Dai explained the zest and I completely agree with him. In addition, I would like to provide you some real-life difference besides.
Web Service:
As Web Service basically, used WSDL which used to communicate with SOAP or XML base service. However, the main challenge in Web Service was to handle cross-platform request. We used to add service reference as following way: While developped Web Services.
Web API:
Considering these drawbacks, Microsoft, latter on developed the Web API more specifically, Asp.net Web API which provide the robust functionality for cross platform development using REST pattern mostly used Json data. It doesn’t mean that web service cannot do that, but not robust as Web API now a days. Unlike, web service we don’t need to go through any integration hassle as above which we can directly develop using asp.net core project and can open the route to call from anywhere.For instance below example:
[ApiController]
[Route("api/VehicleFilter")]
public class VehicleFilterController : ControllerBase
{
private readonly ApplicationDbContext _context;
private readonly IWebHostEnvironment _environment;
public VehicleFilterController(IWebHostEnvironment environment, ApplicationDbContext context)
{
_environment = environment;
_context = context;
}
[HttpGet]
public async Task<IActionResult> GetAllFilter()
{
string VehicleName = "Hatchback";
var sqlCommand = $"EXEC GetVehicleByTile {VehicleName}";
var vehicleFilterValues = await _context.VehicleFilter.FromSqlRaw(sqlCommand).ToListAsync();
return Ok(vehicleFilterValues);
}
}
To summarize, Web API provides more flexibility and robustness and of course its lightweight while writing any new method. Where web service leads to some demerits to the developer.
I found a lot of pages regards to this issue, but none of the Solutions worked.
I have a JavaScript Button in the View that is calling a WebApi method(C#)
$('#btn-Sign-in', this).click(function () {
var apiUrl = 'https://localhost:44391/api/test';
fetch(apiUrl).then(response => {
return response.json();
}).then(data => {
// Work with JSON data here
console.log(data);
}).catch(err => {
// Do something for an error here
});
});
This is My Webapi method that is calling external api:
[RoutePrefix("api")]
public class TestController : ApiBaseController
{
[HttpGet]
[Route("redirectforauth")]
[RequiresPermission("Home:View")]
[HttpGet]
[Route("test")]
[RequiresPermission("Home:View")]
public async Task<IHttpActionResult> ConnectExternal()
{
var request = new FlurlRequest("URL of an external website")
.SetQueryParam(...)
.SetQueryParam(...)
.SetQueryParam(...)
.SetQueryParam(...);
var redirectUrl = request.Url.ToInvariantString();
return Redirect(redirectUrl);
}
when I am running the project, I am getting this error:
CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
This error is due to your web application URL & C# API URL are not having same origins (not running on same port or same hosts). Two URLs have the same origin if they have identical schemes, hosts, and ports.
EX: Your C# URL https://localhost:44391 is different from your web application URL.
First, to make sure that you are getting the error due to your c# api & not due to the external api, comment out your external api request code inside your action, and return something directly from your api to web application. (If the error is from external Api, that external api needs to handle this to allow access to other origins.)
If you are getting the error due to your c# api & not due to the external api, one approach to do this is, by enabling CORS in your C# WebApi application. You can enable CORS per action, per controller, or globally for all Web API controllers in your application.
You can install this nuget package in your C# API application:
Microsoft.AspNet.WebApi.Cors
In App_Start/WebApiConfig.cs, add this code to the WebApiConfig.Register method:
config.EnableCors();
Next, add the [EnableCors] attribute to your TestController class, with your web application URL.
Ex: if your web application URL is localhost:3000, add it in origins as below.
[EnableCors(origins: "http://localhost:3000", headers: "*", methods: "*")]
public class YourController : ApiController {
// Your methods...
}
Now the AJAX request from your Web Client should work. The GET, PUT, and POST methods are all allowed.
For more details on how to enable CORS & how it works:
Enable cross-origin requests in ASP.NET Web API 2
POST /api/services/app/Company/Create is the URL we normally get when we create App Service in ASP.NET Boilerplate.
How can I achieve POST /api/services/app/Company using App Service? Because if I use OData, then some response format is not in ABP response format.
Here, POST is the HTTP method and Create is the name of the method in CompanyAppService of my ABP Application project. What I want is when I consume this API on any web app, then I should be able to call this API at /api/services/app/Company with HTTP method POST. I don't want to use Create, Update, Delete, Get, GetAll in URL that we are going to use while calling in web application.
You can achieve this by following way.
[HttpPost("api/services/app/Company")]
public async Task CreateCompany(CompanyDetailsDto input)
[HttpDelete("api/services/app/Company")]
public async Task DeleteCompany(EntityDto input)
[HttpGet("api/services/app/Company")]
public async Task GetCompany(EntityDto input)
[HttpPut("api/services/app/Company")]
public async Task UpdateCompany(CompanyDetailsDto input)
We have a server which has several types of api (custom XML API based on httplistener, SOAP API based on WCF and REST API based on WEB API). We want to move all API's to WEB API (there are many reasons) and it should be backward compatible.
One of the reason to support url structure: services/service1. services/service2. And in this case it should be on one port. It is intranet application which is distributed to multiple customers and it should be easy to deploy, install. So, we can not have a long configuration on customer side (proxing and otherts).
Are there easy way for implementation SOAP service on web api? At first look should be easy way to parse httprequest to typed soap envelope (based on existed contract) and serialize a answer. Of course, there many actions and data types in contract.
PS: I do not want to look into servicestack:)
Update:
The problem I described above can be fixed by proxing http request to soap service (It can work only with basichttpbinding without security. If WCF service require NTLM authentication it won't work):
[HttpPost]
public async Task<IHttpActionResult> SoapAction()
{
var httpClient = new HttpClient();
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://localhost:8111/soap")
{
Content = this.Request.Content
};
foreach (var header in this.Request.Headers)
{
httpRequestMessage.Headers.Add(header.Key, header.Value);
}
var responseMessage= await httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);
return ResponseMessage(responseMessage);
}
But I still want to know are there any SOAP parser in C# because my server supports NTLM authentication.
I wouldn't recommend to mix the technologies. Have one project for SOAP Apis and another one for the WebApi, sharing the same logic.
You have then one url for soap, the other one to webapi.
Edit:
I wouldn't do the SOAP Parser at all. That was the power of WCF and would keep on using it.
Since proxing is not an option (Which could be done in web.config and easily deployed), I would create a WebAPI endpoint which would redirect to SOAP API.
[HttpGet]
public IHttpActionResult Service1()
{
return Redirect("http://service.com/soap/services/service1");
}
Later, when migrating the logic, use the service itself.
[HttpGet]
public IHttpActionResult Service1()
{
var result = new ServiceLogin1().Execute();
if(result == null)
{
return StatusCode(HttpStatusCode.NoContent);
}
else
{
return Ok();
}
}
I think this is already answered here ASP.NET WebAPI + Soap
If what you are asking for is how to create REST wrappers that call into the SOAP implementations then library's like ServiceStack do this for you but if you want to do it yourself with WebApi it's pretty easy. Just make a separate project that has your SOAP service references in it wrapped in some sort of abstraction and then reference that in your WebApi project and call into it from your REST endpoints.
If what you are asking is how to host the SOAP interfaces in WebApi I think you are just making more work for yourself. Use the WCF scaffolding that MS has provided. WebApi for REST services, WCF for SOAP.
I'm implementing a REST Web API. I'm using the examples from Adam Freeman's Pro ASP.NET MVC5 as a starting point but adapting it into the Web API way of doing it.
The below is my code:
public class AdminController : ApiController
{
private IUserRepository _repository;
public AdminController(IUserRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
return View(_repository.Users);
}
}
In the book, AdminController implemented Controller not ApiController, but if I do that then I get errors about there being no parameterless constructor. I need the constructor to take parameters so that I can inject the dependencies. So that's why I changed to ApiController but now it won't recognise View.
What do I need to use instead of View for an ApiController?
I did find this question but the answer was basically "you don't need to use an ApiController here, just use Controller" so that didn't help me.
You are having two different problems. Let's solve them separately.
1. Do I need to use ApiController or Controller?:
Someone already answered this here: Difference between ApiController and Controller in ASP.NET MVC.
The first major difference you will notice is that actions on Web API
controllers do not return views, they return data.
ApiControllers are specialized in returning data. For example, they
take care of transparently serializing the data into the format
requested by the client.
So, if you want to return a View you need to use the simple ol' Controller. The WebApi "way" is like a webservice where you exchange data with another service (returning JSON or XML to that service, not a View). So whenever you want to return a webpage (View) for a user you don't use the Web API.
In other words, the Web API is about returning data to another service (to return a JSON or XML), not to a user.
2. But if I use Controller then I get "parameterless constructor" errors.
Okay, now we've got to your real problem. Don't try to reinvent the wheel and fight with ASP.NET about doing dependency injection! A tool already exists to resolve dependency injection and sort out the "parameterless constructor" error: Ninject.
If you're already using Ninject and still getting that error, you're doing something wrong with Ninject. Try to repeat the installation and configuration steps, and see some tutorials or questions about parameterless error with Ninject use
An API controller is a controller which provides a RESTful response. You cannot return a view from it. Instead of doing that, consider returning a response (values) which forces the client that asks for an action to redirect to another controller (passing arguments if necessary) to return a view.
Your case does not look like you need an API; in this case just try this (change what you inherit):
public class AdminController : Controller
{
private IUserRepository _repository;
public AdminController(IUserRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
return View(_repository.Users);
}
}
I will try to explain what an API should do anyway. A web API should return just information. An HTTP response about what the action should do.
For example, to create a new customer, an API should have a method (decorated with POST) to get information from a client application (could be anything: web, windows, mobile, windows service, etc.). This information should be processed by the API (or other layers in a possible architecture) and return an HTTP status code, for example 200 - OK if it was fine or 400 - Bad Request if an error happened. So, when I said you should consider returning information, you could just return a DTO object to provide a result.
Both types of project use MVC principles, but they are used in a different context. Take a look at these articles:
Web Api 2.0 Tutorial
Difference between MVC and WEB API
Also take a look at the ASP.NET website about how they work:
ASP.NET WEB API
ASP.NET MVC
Use Controller to render your normal views. ApiController action only return data that is serialized and sent to the client.
But still you want to render view from APIcontroller, then there may be a another way, click on below link for reference :
https://aspguy.wordpress.com/2013/09/10/web-api-and-returning-a-razor-view/