For a MVC 5 application, when I debug the solution, then only on first request, break point hits the RouteConfig class, next request on wards, it's not filling the route table again.
Question, where the routing table stored, how it will match on second request?
Thanks,
The RouteTable is implemented as a singleton. In ASP.NET (or MVC), a singleton's lifetime lasts until the application pool is recycled.
namespace System.Web.Routing
{
using System;
using System.Runtime.CompilerServices;
[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
public class RouteTable
{
private static RouteCollection _instance = new RouteCollection();
public static RouteCollection Routes
{
get
{
return _instance;
}
}
}
}
So all web requests will use the same instance of the RouteTable, first, second, or otherwise.
The RouteTable is automatically repopulated when the application pool recycles because it is initialized within the Application.Start event (usually in Global.asax). This event only fires 1 time when the application first starts (or when the application pool recycles).
Related
I have a web application acting as a gateway to a variety of internal services. These services are consumed by using a single instance of HttpClient, instantiated at startup (i.e. Startup.cs)
After a certain period of time, something is causing our HttpClient to stop hitting our APIs and immediately fail with HTTP 502 errors for every call using that client. (Note that I can still hit our APIs using other means, such as Postman)
Also be aware that this is all deployed to a variety of AppServices in Azure.
Any ideas as to what could corrupt HttpClient in this manner?
Thanks,
-Tim
This error is usually given when you are behind a proxy server.
If you are using a proxy you will probably have to authenticate the http client again.
Another possibility is to generate the Singleton instance again when it gives an error, for Example Singleton.killInstance(); If your implementation is like this:
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
public static void Singleton killInstance()
{
instance == null
}
}
Whatever the error might be, your httpclient request is causing your web server to crash. In order to investigate it, you need to go to to the Event Viewer of your AppService.
Here are the steps to launch the event viewer:
Go to Kudu management site of your website (ie https://{sitename}.scm.azurewebsites.net
Open menu item: Tools => Support
Choose relevant Azure AD Directory of your website
Click on Analyze => Event Viewer.
Check the error messages
I need to add an IIS module for some processing. Here is my module:
namespace MyNamespace
{
public class MyModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
//I hope to do some work here ONLY once for all requests
context.ReleaseRequestState += new EventHandler(myHandler);
}
#endregion
public void myHandler(Object source, EventArgs e)
{
//do some work...
}
}
}
I need to do some resources-consuming work in the Init() method. I HOPE that Init is called ONLY once in a website and is called again only when the website is restarted in IIS Manager.
Can an expert in this tell me whether Init() works as I hope for?
Thanks!
For ANY requests being carried out, it will always call this method so no, it is not for the first time the app pool spins up. What you may wish to do is have a static variable in there to see if it truly is the first time its been hit and if not, carry on with what you need otherwise ignore it. ensure you lock around the portion of code when you are setting the variable to true.
Remember, IIS has application pools which websites use (generally speaking). There will be multiple concurrent requests coming into IIS to process and what happens? The app pool executes to serve the request to the website therefore multiple "hits" will be executed for the Init() for the HttpModule but once per application, if that makes sense.
Every one of them initializes their own list of modules.
you DO have the option of using the Application_Start event in the global asax which will only ever execute once per application (when the app pool spins up and the request is being submitted) - perhaps you can use this for your needs, which would be a better option.
I wish to create a service which will be hosted on Server A (eg URL: http://servera:807). But my main application needs to be hosted on Server B (eg URL: http://serverb:801).
I am curious if this is possible or not? The reason my service and main application need to be on different servers are for reasons beyond my control. The current system uses WCF with the same setup and I'd like to move away from this.
In the examples the Service and Client all seem to be hosted in the same location / in the same solution
Below is a potential set up for solutions/projects. It's simplistic and incomplete but I think helps illustrate one possible set up. You would also need to consider how you want to handle Session information and Authentication since the MVC and ServiceStack handle this separately. See CustomAuthenticationMVC
ServerA.sln (ASP.NET Web Application)
ServiceModel project - holds requests objects and dtos (this can be shared between ServerA and ServerB solutions)
ServiceInterface project - has the Service implementations
Global.asx - has Application_Start method to configure ServiceStack
ServerB.sln (MV4 application)
ServiceModel project (shared)
Views
Models
Controllers
Example of classes in ServiceModel Project:
[Route("/Foos")]
public class Foos : IReturn<FoosResponse>
{}
public class FoosResponse
{
public FoosResponse()
{
this.ResponseStatus = new ResponseStatus();
}
public ResponseStatus ResponseStatus {get; set;}
}
Examples of classes in ServiceInterface project
public class FoosService : Service
{
public FoosResponse Get(Foos request)
{
return new FoosReponse();
}
}
Example how to call ServiceStack API within MVC4 application
public class FoosController
{
public ActionResult Index()
{
var client = new JsonServiceClient("http://servera:807");
var response = client.Get(new Foos());
return View(response);
}
}
I'm trying to initialise my dependency registration for a WCF service running in an Azure Web Role, but I'm seeing a very unusual behaviour whereby the static constructor of my class is being invoked twice.
This is the Dependencies class I'm using as a registry point for the dependencies of the application.
public static class Dependencies
{
private static IUnityContainer container;
static Dependencies()
{
Dependencies.container = new UnityContainer();
}
public static IUnityContainer Container
{
get
{
...
}
set
{
...
}
}
public static void ConfigureContainer()
{
var container = new UnityContainer();
// Configure container.
Dependencies.container = container;
}
}
In my overload of RoleEntryPoint.OnStart(), I make a call to a static ConfigureContainer method to set up the container with my dependencies registered:
public override bool OnStart()
{
// Configure container for dependency resolution.
Dependencies.ConfigureContainer();
return base.OnStart();
}
My expectation is that the static members of the Dependencies class should be initialised by this code and will be available to the components of the application.
What I'm seeing (using a breakpoint and the VS2012 debugger) is that the static constructor of Dependencies is being called twice: once during the original initialisation of the application and again during first request to the service. Subsequent requests don't invoke the static constructor (as expected).
I'd love to hear an explanation of why the runtime is behaving this way and what I should be doing instead to produce my static registry of dependencies.
It's likely because when you host a webrole in full IIS, the RoleEntryPoint code and the rest of the web application run in different AppDomains.
http://blogs.msdn.com/b/windowsazure/archive/2010/12/02/new-full-iis-capabilities-differences-from-hosted-web-core.aspx
By default you use "full IIS" mode in a web role and you get two processes - IIS worker process for handling HTTP requests and role worker process for running RoleEntryPoint descendant code. Depending on how your code is designed you may end up using that static constructor in both processes and then it'll be invoked twice.
I have following service
public class AppService : AsyncServiceBase<EvaluateStock>
{
public IBus Bus { get; set; }
public override object ExecuteAsync(EvaluateStock request)
{
// this will block the incoming http request
// unitl task is completed
// long computation
// Bus.Publish(result)
}
}
which gets called by different consumers following way
POST
http://srv1/app/json/asynconeway/EvaluateStock
Using asynconeway I was assuming that it will allow me to achieve fire and forget as WCF does with IsOneWay. But seems is not the case.
Do I miss something ?
AsyncServiceBase has been deprecated as ExecuteAsync is now in ServiceBase which is what gets called when a request is made to /asynconeway/XXX pre-defined endpoint.
Rather than overriding ExecuteAsync the recommended approach is to implement IMessageFactory which is what gets called if an IMessageFactory has been registered in the AppHost IOC. If an IMessageFactory wasn't registered than it just gets executed Sync - at which point if you still wanted it non-blocking you would override it. The impl for ExecuteAsync is at:
// Persists the request into the registered message queue if configured,
// otherwise calls Execute() to handle the request immediately.
//
// IAsyncService.ExecuteAsync() will be used instead of IService.Execute() for
// EndpointAttributes.AsyncOneWay requests
public virtual object ExecuteAsync(TRequest request)
{
if (MessageFactory == null)
{
return Execute(request);
}
BeforeEachRequest(request);
//Capture and persist this async request on this Services 'In Queue'
//for execution after this request has been completed
using (var producer = MessageFactory.CreateMessageProducer()) {
producer.Publish(request);
}
return ServiceUtils.CreateResponseDto(request);
}
IMessageFactory (client)/IMessageService (server) is apart of ServiceStack's Messaging API which allows you to publish messages for deferred execution later. See the Redis and Messaging wiki for an example of an end-to-end solution that uses the built-in Redis IMessageService. There are also InMemory and RCon IMesssageService's available and it should be easy to create your own as well.
Future Async support
There is also an async branch that has ServiceStack running on IHttpAsyncHandler and already has a functional alpha build available for you to try at: ServiceStack-v4.00-alpha.zip
With this change ServiceStack supports Task<> as a return type on services. You only need to register the Task<> plugin. To see a full example look at this integration test.