I've recently installed VS 2012 and .net Framework 4.5, and everything is mostly ok, except that I occasionally get the error:
This operation requires IIS integrated pipeline mode.
I of course have Managed pipeline mode: Integrated in IIS.
protected override void OnLoad(EventArgs e)
{
var st = new StackTrace(true);
string message = String.Format("Redirect to url: {0}, Stack Trace:\r\n{1}", url, st);
Trace.TraceInformation(message);
}
protected void Application_Start(Object sender, EventArgs e)
{
Trace.Listeners.Add(new OurAspTraceListener(Context));
}
And the Custom Trace listener is pretty simple.
private class OurAspTraceListener : TraceListener
{
private readonly HttpContext _context;
public OurAspTraceListener(HttpContext context)
{
_context = context;
_context.Trace.IsEnabled = true;
}
public override void Write(string message)
{
_context.Trace.Write(message); // it's throwing here.
}
public override void WriteLine(string message)
{
_context.Trace.Write(message);
}
}
It's really weird because if I just hit refresh it continues without any problem.
Any help would is appreciated,
Thanks.
Which version of IIS do you have ?
If you use IIS 7, make sure you have the application pool type set to integrated and not classic. The integrated pipeline mode is IIS 7 specific.
Related
I try to build notifications for dashboard in my WebForms application under .NET 4. I have downloaded SignalR version 1.2 (both .net client and server) and prepared a simple notification example. Unfortunatelly it does not work and I can't figure why. If I type http://myserver.com/notificationSample/signalr/hubs javascript proxy appears and it looks ok.
Take a look at the implementation below, does someone see any bug?
a) Hub implementation
[HubName("NewMessage")]
public class NewMessageNotifier : Hub
{
public void NotifyDashboards()
{
Clients.All.NewMessageCreated();
}
}
b) Notification caller (server) ~/Pages/NotificationCaller.aspx
public partial class NotificationCaller : Page
{
private HubConnection connection;
private IHubProxy proxy;
protected void Page_Load(object sender, EventArgs e)
{
connection = new HubConnection( "http://myserver.com/notificationSample" );
proxy = connection.CreateHubProxy( "NewMessage" );
connection.Start().Wait();
}
// it is handler for onclick event on Button control
protected void NotifyDashboard(object sender, EventArgs e)
{
proxy.Invoke( "NotifyDashboards" ).Wait();
}
}
c) Dashboard (client, listener) ~/Pages/Dashboard.aspx
public partial class Dashboard: BasePage
{
private HubConnection connection;
protected void Page_Load(object sender, EventArgs e)
{
connection = new HubConnection( "http://myserver.com/notificationSample" );
var proxy = connection.CreateHubProxy("NewMessage");
proxy.On("NewMessageCreated", ShowNotification);
connection.Start();
}
private void ShowNotification()
{
ShowAlert("New message added!");
}
}
you are using it in the wrong way
First
both b and c are clients, the server gets started by itself, all you need is to do is to add
RouteTable.Routes.MapHubs();
to the
Application_Start
method in global.asax
Second
if you are going to use a webpage as the client, you should do it from javascript, as what you are doing now will not work because the
connection.Start()
is async and the request will end before it does anything, and it will not wait for incoming connections because all will be disposed
Now how to do it? it will take many pages here, so here are a few links
A Simple Tutorial
The Hubs Server API
The Hubs JavaScript API
and in case you missed it, a video that explains what is SignalR, how it works and a simple app which you can find here
I'm publishing my asp.net site with iis( my local machine has iis v8, server's iis v7 ).
But I want to start a function in Global.asax.cs immediately without calling a page.
*When I call a page, global.asax.cs Application_Start method launches. I want to launch it without a page call request.*
namespace ProductService.XmlFeed
{
public class Global : HttpApplication
{
protected void Application_BeginRequest(Object sender, EventArgs e)
{
FtpUploaderMain.RegisterCacheEntry(); //this method I want to start without page call
}
void Application_Start(object sender, EventArgs e)
{
SimpleLogger.WriteLog("Application Started without a page call","D:\\log.txt");
RegisterRoutes();
//FtpUploaderMain.RegisterCacheEntry();
}
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("Products", new WebServiceHostFactory(), typeof(ProductXmlFeedService)));
}
}
}
You can use PreLoad enabled feature of IIS8 -
For IIS 7.5 use application- initialization -
http://www.iis.net/downloads/microsoft/application-initialization
Currently my product page URL is like
http://www.localhost:80/products/default.aspx?code=productCode
I want to access product page with
http://www.localhost:80/productCode
I have used HTTP module for this.
public class UrlRewritingModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
context.AuthorizeRequest += new EventHandler(context_AuthorizeRequest);
}
void context_AuthorizeRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
if (some condition)
{
context.RewritePath(url);
}
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
//We set back the original url on browser
HttpContext context = ((HttpApplication)sender).Context;
if (context.Items["originalUrl"] != null)
{
context.RewritePath((string)context.Items["originalUrl"]);
}
}
}
I have register it in web.config and it is working fine. But when I deploy it in IIS that session and application variables are not throwing null referent Exceptions.
Can anyone help me?
Edit: Do it require extra code to access session/ Application variable for rewritten URLs
?
Have you tried using HTTPContext.Current?
I was able to solve issue (accessing session and application variables in subsequent pages rewritten by custom handler) by adding runAllManagedModulesForAllRequests="true" attribute in modules in web.config.
There is a new app setting in asp.net 4.5
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
code like this can run in asp.net 4.0
protected void Button1_Click(object sender, EventArgs e)
{
CallAysnc();
}
public void CallAysnc()
{
AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(Guid.NewGuid().ToString());
WebClient client = new WebClient();
client.DownloadStringCompleted += (object sender, DownloadStringCompletedEventArgs e) =>
{
asyncOp.PostOperationCompleted(CallCompleted, e.Result);
};
client.DownloadStringAsync(new Uri("http://www.google.com"));
}
private void CallCompleted(object args)
{
Response.Write(args.ToString());
}
But it doesn't work in asp.net 4.5,and when I remove the new appsetting,it works again!
So what's the meaning of "UseTaskFriendlySynchronizationContext" ?
Regarding UseTaskFriendlySynchronizationContext, from Microsoft Forums:
That tells ASP.NET to use an entirely new asynchronous pipeline which
follows CLR conventions for kicking off asynchronous operations,
including returning threads to the ThreadPool when necessary. ASP.NET
4.0 and below followed its own conventions which went against CLR guidelines, and if the switch is not enabled it is
very easy for asynchronous methods to run synchronously, deadlock the request, or otherwise not behave as expected.
Also, I think AsyncOperationManager is intended for desktop applications. For ASP.NET apps you should be using RegisterAsyncTask and setting <%# Page Async="true", see here for more details.
So using the new c# keywords your example would be:
protected void Button1_Click(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(CallAysnc));
}
private async Task CallAysnc()
{
var res = await new WebClient().DownloadStringTaskAsync("http://www.google.com");
Response.Write(res);
}
The aim is to support the following by release but is not currently supported in the beta:
protected async void Button1_Click(object sender, EventArgs e)
{
var res = await new WebClient().DownloadStringTaskAsync("http://www.google.com");
Response.Write(res);
}
More details, quoted from ASP.NET 4.5.1 documentation for appSettings on MSDN:
aspnet:UseTaskFriendlySynchronizationContext
Specifies how asynchronous code paths in ASP.NET 4.5 behave.
...
If this key value is set to false [default], asynchronous code paths in ASP.NET 4.5 behave as they did in ASP.NET 4.0. If this key
value is set to true, ASP.NET 4.5 uses code paths that are optimized
for Task-returning APIs. Setting this compatibility switch is
mandatory for WebSockets-enabled applications, for using Task-based
asynchrony in Web Forms pages, and for certain other asynchronous
behaviors.
There is a HttpModule that change Server field in Response Headers. But it does not work in ASP.NET/IIS7 classic mode. what is the solution for remove or change Server field in reponse header?
public class CloakHttpHeaderModule : IHttpModule
{
public void Init(HttpApplication app)
{
app.PreSendRequestHeaders += new EventHandler(context_PreSendRequestHeaders);
}
public void Dispose()
{
}
private void context_PreSendRequestHeaders(object sender, EventArgs e)
{
var context = ((HttpApplication)sender).Context;
context.Response.Headers.Set("Server", "Apache 2.0");
//HttpContext.Current.Response.Headers.Set("Server", "WSGIServer/0.1 Python/2.6.1");
}
}
You can't do this unless you're running at least IIS7, Integrated Pipeline Mode and .NET 3.0. The documentation states this:
HttpResponse.Headers Property
The Headers property is only supported with the IIS 7.0 integrated
pipeline mode and at least the .NET Framework 3.0. When you try to
access the Headers property and either of these two conditions is not
met, a PlatformNotSupportedException is thrown.