How to create a custom Maintenance page returning 503 for Azure? - asp.net-mvc-3

I'm trying to set up a custom Maintenance page on MVC 3 but specifically on Azure. Basically to keep it SEO friendly i need to return a 503 (Service Unavailable). All my other custom error pages work in Azure (eg 404) following the usual
<customErrors mode="On">
<error statusCode="404" redirect="404.htm"/>
<error statusCode="503" redirect="503.htm"/>
</customErrors>
The 404 page works but the 503 is not followed and i simply get an ugly service unavailable page. I have the 500 error working fine through error.cshtml and the standard HandleErrorAttribute.
I even try returning my own ActionResult from an ActionFilter by using the following
public class SiteDownForTestingResult : ActionResult
{
public SiteDownForTestingResult() : base()
{
}
public override void ExecuteResult(ControllerContext context)
{
var path = System.Web.Hosting.HostingEnvironment.MapPath("~/app_testing.htm");
var response = context.HttpContext.Response;
response.Clear();
response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
response.StatusDescription = "Service Unavailable.";
response.WriteFile(path);
response.End();
}
}
were app_testing is my custom page, and then setting the filterContext.Result = new SiteDownForTestingResult(); from OnActionExecuting of an ActionFilter and still i'm greeted by the plain 503 'service unavailable' page
Is this something to do with application.config on Azure locking something or other i don't know about. This works fine on IIS7 and my local box, but the Emulator and Cloud both give no joy.
Any help would be appreciated.

Based on my understanding custom 503 error is generated directly from https.sys mostly when app pool is not available. And now when there is no app pool none of your setting is going to work at your custom error settings will be specific to app pool. Also most of the search engine depend on 503 error code in return so display search result properly and that's why customization of this error is not typically done at application level.
As you referenced Windows Azure Emulator, I believe you are using Windows Azure Web Role. With Windows Azure Web Role you can customize IIS with AppCmd.exe in a StartUp task, which is your maximum level of customization. You can not reach HTTP.sys level of customization in Windows Azure so customization 503 error may not work on Windows Azure.

Related

Blazor app not running server code when on hosted server

I have a blazor web assembly app and I have 3 projects that were created. The client, server and shared. I assume all of these are deployed as standard when using the webdeploy?
The site works in that it displays the pages etc. However when I go to a page that contacts the server project via the Http.PostAsJsonAsync() method, I get the blazor error page (which I setup to say "oops").
Obviously I get no details as to what is going wrong. So I have no idea what is happening. Is the server app compiled into the Web assembly app? If so why would it not be running the server code? Plus I suppose the other question is how do I get it to report the error so that I can get an idea as to what is going wrong?
It works absolutely fine when running it through Visual Studio.
This is the first time I have deployed to a hosted server so there is a very high chance I have done something wrong...
The method I am calling literally does nothing other than returning a 200 message. So I assume the issue is with calling the server method itself.
Firstly, use Logging:
https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/logging?view=aspnetcore-5.0&pivots=server
#inject ILogger<MyComponent> Logger
Then wrap your Http.PostAsJsonAsync() call in a Try Catch block.
Log the error in the Catch block:
try
{
await Http.PostAsJsonAsync()
}
catch (Exception e)
{
Logger.LogError(e);
}
After deployment, edit your web.config file:
<aspNetCore processPath="dotnet"
arguments=".\Hospitillity.App.Server.dll"
stdoutLogEnabled="true" // <<< MAKE THIS true
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess">
Note, the setting stdoutLogEnabled="true". This will cause your hosting provider to generate log files.
Then recycle your app pool on your hosting provider.
Connect to your website again, and after the error you should have some more details about error logged in
\logs\stdout_nnnnnnnnnnnnnn_nnnnnn.log
on the hosting server.
Take it from there ...

Deploy ASP.net core 2.1 WEB API to IIS using Visual Studio Code

Working on an ASP.net core 2.1 web API project. I need to enable the API so that it can be accesed by client applications that we also have under developement.
So far, the only way I've found to publish to IIS is by doing a manual process:
Run dotnet publish -c Release
Copy the files in bin\Release\netcoreapp2.1\publish\ to my IIS Web App folder
I wonder if there is a more straight forward way of doing this.
Also It takes quite sometime to build this release, so for a development environment it's quite a slow process. The problem is that we cannot allow external access to the WEB api when running with F5 on the Integrated test server. How can we enable an more agile testing environment?
Another issue is that when calling for example fetch('MyAPIServer/api/MyItems') from a javascript application, I get a CORS error:
Failed to load http://localhost:86/api/shit: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8082' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled
Is enabling CORS absolutely necesary when developing this type of apps?
If I fetch like this:
fetch(
`http://localhost:86/api/shit`,{mode: 'no-cors'}
)
I get:
Uncaught (in promise) SyntaxError: Unexpected end of input
at eval (Pos.vue?7f37:68)
As far as the CORs issue goes you can add the following to your startup:
public void ConfigureServices(IServiceCollection services)
{
// Rest of config stuff ...
services.AddCors();
}
Then in you will also need to add the following.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(builder =>
{
builder.WithOrigins("http://localhost:8080",
"http://localhost:8081",
"http://localhost:8082")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
app.UseMvc();
}

Elmah works on localhost, but not on production?

In my ASP.NET MVC 3 app, I've configured Elmah, and then Elmah.MVC for error logging. Both of which log just fine when running on localhost (Windows 7, IIS 6.1). On a production server (2008 R2, IIS 6.1), no errors are logged. I can browse to the /elmah directory in the site without problem (I've allowed remote access for now.) I've set the proper permissions to a folder for XML logging but nothing logged. I back-tracked to use the "in memory" logger, still no log. I've made sure modules and handlers were referenced correctly in both system.web and system.webserver.
I've browsed a lot of posts related to Elmah config issues, permissions, etc., but have not yet found the cause of this.
Are there other security/permissions issues that I'm missing on the production server related to Elmah? What else could be causing this?
Make sure you do NOT have "Read Only" checked on the folder. thanks
Not sure if this is still current but I was having a similar issue: it all worked perfectly on my local computer and on the web server when you had customErrors mode="Off" but if you changed customErrors to RemoteOnly then it would only work if you accessed the website locally.
The solution was to add a new Elmah filter on the FilterConfig section that guarantees elmah will always log the errors regardless of the customErrors mode. Here is the post with details: http://forums.asp.net/t/1687875.aspx?Elmah+Error+Log+is+not+working+my+production+Server
Here is the code snippet (credit to the person on the post):
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new ElmahHandledErrorLoggerFilter());
filters.Add(new HandleErrorAttribute());
}
}
public class ElmahHandledErrorLoggerFilter : IExceptionFilter {
public void OnException(ExceptionContext context) {
//if (context.ExceptionHandled) // Log only handled exceptions, because all other will be caught by ELMAH anyway.
//We want elmah to log ALL exceptions
ErrorSignal.FromCurrentContext().Raise(context.Exception);
}
}

IIS Express Returning HTTP 400 for WCF RESTful Service

I have a WCF RESTful Web Service (using webHttpBinding) that is returning a 400 when I try to call a web service method on it.
If I go to mywebservice.svc, I get the standard WCF web service page. But if I go to /mywebservice.svc/some/rest/service/url, I get an Http 400. Every single time. Doesn't matter the parameters, or the method being called.
Here's what we've looked at so far:
Looked at IIS Express logs. There is no Win32 status (i.e. status 0) to go along with the HTTP Status
Turned on WCF logging. Nothing is logged by WCF, which suggests the request isn't even making it that far.
Tried debugging our method, but the breakpoint never gets hit.
Tried running the service under Cassini. Same result (http 400).
Tried another user on the problematic machine. Same result.
We know that this works on other machines. The problematic machine is using VS 2010 on Win XP. We are using WCF 4.0
I know there isn't much to go on here because we don't have a specific error message, but given where we've looked, does anybody have any suggestions on where to look next?
UPDATE: Added Code Samples
Here is the definition of my with one method, and the implementation of that method.
[ServiceContract]
public interface IMAMDataWebService
{
[WebGet(UriTemplate = "/Contracts/{taxID}", ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
ContractCollection Contracts(string taxID);
}
public ContractCollection Contracts(string taxID)
{
ContractCollection contracts = new ContractCollection();
try
{
contracts = _contractService.GetContracts(taxID);
}
catch (RstsException rEx)
{
if (!rEx.Logged)
_errorLogger.LogError(rEx);
WebFault.ThrowFault(rEx, HttpStatusCode.InternalServerError);
}
catch (Exception ex)
{
RstsException rEx = new RstsException(ex);
_errorLogger.LogError(rEx);
WebFault.ThrowFault(rEx, HttpStatusCode.InternalServerError);
}
if (contracts.Count == 0)
{
WebFault.ThrowFault(Strings.ObjectNotFound, HttpStatusCode.NotFound);
}
return contracts;
}
I'm calling it with a web browser, i.e. MAMDataWebService.svc/Contracts/123456789
I'm convinced this has to be a permissions problem, but I"m not sure what. It works on all our Win 7 machines using VS 2010, but a few users still have XP and they're the ones with the problem. But without any errors, it's hard to tell what's going on.

MVC3 Application Inside Webforms Application Routing is throwing a HttpContext.SetSessionStateBehavior Error in IIS7.5

I'm running a mixed MVC Application inside a sub folder of a web forms application.
Everything worked great in VS 2010 debug (Cassini) but when I deployed to IIS7.5
I got the following error:
'HttpContext.SetSessionStateBehavior' can only be invoked before
'HttpApplication.AcquireRequestState' event is raised.
It errors on the last line (httpHandler.ProcessRequest(HttpContext.Current);) in the default.aspx file of the MVC application sub folder.
public void Page_Load(object sender, System.EventArgs e)
{
string pathToRewriteTo = Request.Path.ToLowerInvariant().Replace("default.aspx", "Home/Index");
HttpContext.Current.RewritePath(pathToRewriteTo, false);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext.Current);
}
However if I manually navigate to Home/Index from the MVC root folder I can see my application fine from there.
I've looked up the error being thrown and I only find answers dealing with server transfers and not MVC routes.
I have also already checked my IIS7.5 configuration for the route handling module, Application pool running in integrated mode, etc.
Any help would be appreciated.
We faced a similar issue. There are changes to MVCHttpHandler in MVC2 and above.
You need to change it to use httpContext.Server.TransferRequest.
Try the below snippet:
var httpContext = HttpContext.Current;
httpContext.Server.TransferRequest(Url, true); // change to false to pass query string parameters if you have already processed them

Resources