Sorry for my lack of understanding regarding the web stack but this has been haunting me for a couple days.
I am trying figure out how to access Request as a IHttpRequest within the web controllers of the https://github.com/ServiceStack/SocialBootstrapApi example.
It is currently a MVC3 app with ServiceStack's MVC PowerPack. My request always resolves to a System.Web.HttpRequest. I created an extension method on IHttpRequest to check if the current request is coming from a mobile device but it never gets picked up because all my requests are System.Web.HttpRequests instead of a ServiceStack.ServiceHost.IHttpRequest. any help would be great!
You can do something like
var httpReq = System.Web.HttpContext.Current.ToRequestContext().Get<IHttpRequest>();
to turn the request from System.Web.HttpRequest into a ServiceStack.ServiceHost.IHttpRequest.
The requests going into the Controllers of the SocialBootstrapApi examples don't come through the 'ServiceStack pipeline'. The Controllers do inherit from ServiceStackConroller but I think its purpose is to share Session data between MVC and ServiceStack. The ServiceStackContoller doesn't take over the request/response like a request going into the /api path which is handled entirely by ServiceStack in the example project.
Related
I'm new to asp.net mvc and web api. I'm reading a book which says:
ASP.NET MVC uses: System.Web.HttpRequest
and Web API Equivalent is System.Net.Http.HttpRequestMessage
and below is a picture that describes the request and result flow of web api
So my question is, how does hosting environment(which will typically be IIS) know that it should create a HttpRequestMessage object to represent the request from the client? I mean if the application is a MVC application, IIS should create a HttpRequest object instead of HttpRequestMessage, so how does IIS know which one to create?
As you can see from the picture you posted, the HttpRequestMessage exists only inside the "hosting" environment, web browser client does not know anything about that.
In the "hosting" world, IIS app pool is running the code you have built and deployed which knows very well wich framewok you are using as your code also contains the using assemblies you listed, System.Web... or System.Net...
Consider that even if you have shown separation between hosting, Controller and Action, all of that is running in same App Pool in IIS which, again, runs your code so knows what it is about as your IL assemblies were built from your specific source code.
I am not sure if I understand your question but this might be what you're looking for:
I mean if the application is a MVC application, IIS should create a
HttpRequest object instead of HttpRequestMessage, so how does IIS know
which one to create?
You must remember how you differentiate between a normal MVC Controller and a Web API Controller...
WebAPI Controllers enforces this annotation [ApiController] and must inherits from ControllerBase:
[ApiController]
public class PeopleController : ControllerBase {
//Your API methods here
}
A normal MVC Controller only inherits from Controller base class:
public class PeopleController : Controller {
//Your Action methods here...
}
Those already create configuration for your APP which becomes easier for you Hosting environment to know what is going and what to return when.
I hope you find this helpful.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I need to retrieve the content of a JSON feed. I want to use HttpClient for downloading the content. For this purpose I've created a WEB API controller with a Get method which consumes the external API with HttpClient and then returns a List of deserialized content:
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("externalAPI");
MediaTypeWithQualityHeaderValue contentType =
new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
HttpResponseMessage response = await client.GetAsync(client.BaseAddress);
string content = await response.Content.ReadAsStringAsync();
List<MyClass> data = JsonConvert.DeserializeObject<List<MyClass>>(content);
return data;
}
Now I'm going to show this list in client side using Angular and I know how should I do these steps but my question is why should I use a WEB API to consume another external API since I can simply use Angular HttpClient to consume that external API? Is using this WEB API to consume an external API and then return a List to Angular considered as best practices? If no, what is the best way, if I have to use MVC for this purpose?
In my project I consumed external API (which retuns json data), via webapi.
I did it because than my Angular project only have to maintain reference to webapi only i.e. just one url only. and another case in my project is external api url change in Dev,UAT and prod evironment, so i dont want to maintain in my angular project.
So I did it for two reason
Dont want to maintain reference of external api (i.e. URL of external api), and I get only one contact for getting data in my project which is my webapi
URL of external API change in Dev, UAT and PRod so I dont want to maintain that information in my Angular project.
That makes my code of angular more maintainable as if someone else look my code he/she get info that webapi is only location where they should look for ,from where data is coming
Imagine scenario where you are geting data from more then one external API, in that case you have to maintain reference to all API in your Angualr project. So Better to Follow FACADE design pattern, and keep only one point (which WebAPI in this case) which connect with all external api and returns data.
For getting data every 10 min you need to make use of RxJs
var timer$ = Rx.Observable.interval(1000) // 1000 = 1 second
timer$
.subscribe((v)=> this.Service.CalltoExtnerlAPIToGetdata()
.subscribe(data=> this.values = data));
please do unsubscribe from Rxjs Timer when you are not going to consume it to avoid memory leak.. http://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables
Let's say this external API is in the domain abc.com and your app is in the yourapp.com. If abc.com doesn't allow CORS (cross origin request), you won't be able to retrieve data from your angular app that is running in yourapp.com, so buildind a "middleware" in a server might solve this problem.
Anyway, it's not mandatory to build this middleware. If the target API allows CORS, there is no need to do this, and you can write the layer that requests data in your angular app.
The main reason lies within the same origin policy where a given origin, e.g. script executed by your browser, is only allowed to perform requests to an origin which is in the same domain (schema, host and port).
Reasons are mainly security related and have been extensively discussed in this StackExchange question.
A typical approach in MVC implementations to comply to this policy is to perform the HTTP request to your WebAPI using server side code, i.e. from the Controller using HttpClient. Then the Javascript from your View would simply call your Controller's method to retrieve the result.
As a side note, this approach has also the benefit of let you handle any serialization work in your Controller before presenting the data back to the View.
I am beginner in software field. I have one ASP.Net MVC 5 (c#) project. In that I need to write one end point which can be called from a desktop app. Basically desktop app needs to send one integer value to my controller action aka end point. I know how to create a web api. So, I added a WebApi controller in my controller folder namely "HelloController" and below is the code.
public IHttpActionResult Follow(int y)
{
// some code
return Ok();
}
Question 1. Is that it? So, in my desktop app can I call now /HelloController/Follow/34
Question 2. Or Am I totally wrong. And I need some other end point and not the WebApi end point. Please guide me here.
P.S: My desktop app is in VB.Net
That is pretty much it. You'll want to enable Cors. This answer has some good information on setting Cors in ASP.NET MVC 5. There are two main ways to set CORS, the first way in the linked answer(setting the response header HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", "*");) or in the web.config with:
Sorry, my mistake, Cors isn't required from desktop apps to api's. I'm used to setting Cors for web apps.
With the Web Api endpoint, you should be able to consume that from pretty much anything that can create a Web request. I don't specifically know VB.Net or I'd give you an example.
An example web request in C# would look something like this:
var url = someUrl;
using (var client = new HttpClient())
{
var response = await client.GetAsync(url);
var responseString = await response.Content.ReadAsStringAsync();
var deserializedData = JsonConvert.DeserializeObject<MyModel>(responseString);
}
Create an HttpClient, perform a Get request asynchronously. The response string is serialized JSON, so it must be deserialized to a usable model.
That's a basic example, but hope it helps.
Here is a website that contains VB.net examples for REST.
Is it possible to log every HTTP request made to an ASP.NET Web API, even if the request is malformed, or for some other reason fails to route to one of the controllers.
For example, if a POST method has an Order model as it's parameter, an incorrect request will prevent it from ever reaching the controller's POST method. I'd like to alert someone so that actions can be taken to prevent future failures.
Is there a way to capture these requests further upstream from the controller?
Either use Tracing, you need to implement ITraceWriter as shown below
http://www.asp.net/web-api/overview/testing-and-debugging/tracing-in-aspnet-web-api
Or implement message handlers
http://www.strathweb.com/2012/05/implementing-message-handlers-to-track-your-asp-net-web-api-usage/
http://www.asp.net/web-api/overview/working-with-http/http-message-handlers
Message handlers allow you to change message before it comes to HttpControllerDispatcher, and therefore you can handle common problems with routing and action method selection.
But as the last do not hesitate to use AppFabric logging, when you are hosting on IIS, because it can give you information when something is going wrong before requests come to your Web Application. It handles scenarions with global errors in web application, for example errors with web.config.
If you enable tracing in the ASP.NET Web API per Tracing in ASP.NET Web API, the built-in tracing infrastructure will log the information you are after.
In the case of a malformed request that fails content negotiation, you will see an HttpError occur in the DefaultContentNegotiator.
Here is an example of the simple trace for this type of error:
DefaultContentNegotiator;Negotiate;Type='HttpError',
formatters=[JsonMediaTypeFormatterTracer, XmlMediaTypeFormatterTracer,
FormUrlEncodedMediaTypeFormatterTracer,
FormUrlEncodedMediaTypeFormatterTracer]
The trace writer is given a TraceRecord as its input, which will contain the request information as well as optionally any custom information you might want to use.
The Web API will use the trace writer you configure to trace information throughout the lifecycle of requests. You can use trace writer to trace both the lifecycle events as well as your own controller code.
I am working in an environment with many teams who are responsible for specific content on pages. Each team is sharing specific information (common class libraries, and master pages) that each are going deliver different types of content.
Is it possible for an MVC application to do something similar to RenderPartial and pass a model to another MVC application Controller/Action to return content?
So the code for this might look like:
(http://www.mydomain.com/Home/Index)
<% Html.RenderAction("ads.mydomain.com", "Home", "Index", AdModel) %>
Maybe this is not a good idea as another thread has to spin up to server a partial view?
No, RenderPartial/RenerAction can only load views that it can access via reflection, not via HTTP requests to external resources.
If the MVC app for 'ads.mydomain.com' is available to you at compile them then you can utilise its resources via Areas, however it won't pickup the changes if they release a new version to the 'ads.mydomain.com' website without you getting their latest assembly and re-compiling and deploying your app as well.
You can do similar stuff with AJAX where you can load a fragment from another site, however it wouldn't be done server side, and would require the client to have javascript enabled. Also the model would need to be converted to JSON and posted to the request, so its a bit of a hacky solution.
You could write an extension method (lets call it Html.RenderRemote) which does all the work for you of creating an http connection to the target and requests the URL. You'd have to serialize the model and send it as part of the request.
public static string RenderRemote(this HtmlHelper, string url, object model)
{
// send request to 'url' with serialized model as data
// get response stream and convert to string
// return it
}
You could use it as :
<%= Html.RenderRemote('http://ads.mydomain.com', Model');
You wouldn't be able to take advantage of the routes on the remote domain, so you'd have to construct the literal URL yourself, which means if they change your routing rules your URL won't work anymore.
In principal yes, though your question is a little vague.
Have a look at "portable areas" within MvcContrib on codeplex. This technique allows separate teams to develop separate MVC apps that would then be orchestrated by a central application.