We're getting a server configuration error on first load of our page. However, when we then refresh the page loads fine. It can be replicated by refreshing/restarting the server in IIS. First load we get the error, subsequent requests are fine.
Description: An error occurred during the processing of a
configuration file required to service this request. Please review the
specific error details below and modify your configuration file
appropriately.
Parser Error Message: Unrecognized element.
This is happening on line 2 of our web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<!--Redirect selected traffic to index -->
<rule name="Index Rule" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Info:
Windows Server 2012 R2 Standard
Microsoft .NET Framework Version:4.0.30319
ASP.NET Version:4.6.1069.1
Related
I have issue with url Rewrite and ajax request.
here's my config for URL Rewrite:
<rewrite>
<rules>
<rule name="RewriteASPX" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="{R:1}.aspx" />
</rule>
</rules>
</rewrite>
it works with this URL
https://www.example.com/section?data=data
or
https://www.example.com/section
but unfortunately, I have ajax request on my code :
https://www.example.com/section/method
the rule always rewrite the method to be https://www.example.com/section/method.aspx
here's my ajax request script
<script>
debugger
var phone = $('#<%=hidPhoneNO.ClientID %>').val();
var check = $('#<%=hidCheckOutID.ClientID %>').val();
var data = $('#<%=hidData.ClientID %>').val();
var fails = "/Failed?Data=".concat(data)
var suc = "/Success?Data=".concat(data)
$.ajax({
type: "POST",
data: JSON.stringify({ CheckOutID: check, PhoneNo: phone }),
url: "Section/Method",
contentType: "application/json; charset=utf-8",
dataType: "json",
complete: function (data) {
var json = JSON.parse(data.responseText);
/* alert(json["d"]);*/
if (json["d"] === "00") { location.href = fails }
else { location.href = suc }
},
});
</script>
is there any work around to keep the re-write function and done the ajax method call ?
You can use regular expressions in rewrite rules to exclude specific path: Section/Method
<match url="(.*)" /> changed to <match url="^(?!.*section/method).*" />
When the requested URL is https://www.example.com/section/method, it will not follow this rule, the request will not be rewritten.
I have an app service in my azure account, Which is running a node application (Express, Angular and websockets). I am able to serve static contents to my users but the REST APIs are failing with 404 not found error.
Following is my code in my index.js
var os = require('os');
var fs = require("fs");
var bodyParser = require('body-parser');
var express = require('express'),
expressApp = express(),
socketio = require('socket.io'),
http = require('http'),
uuid = require('node-uuid'),
config = require('../config/config.json');
var httpServer = http.createServer(expressApp),
rooms = {},
userIds = {};
expressApp.use(express.static(__dirname + '/../public/dist/'));
expressApp.use(bodyParser.urlencoded({ extended: true }));
expressApp.use(bodyParser.json());
var router = express.Router();
expressApp.use('/api', router);
router.get('/getsomethings', function(req, res) {
res.json(something);
});
expressApp.use('/api', router);
expressApp.listen = function listen() {
httpServer.listen(config.PORT);
};
expressApp.listen();
exports.run = function(config) {
//some code
};
And following is my web.config for app.service
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the app.js file is a node.js application to be handled by the iisnode module -->
<add name="iisnode" path="index.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<!-- Don't interfere with requests for node-inspector debugging -->
<clear />
<rule name="Redirect to https" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
</rule>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^index.js\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}" />
</rule>
<!-- All other URLs are mapped to the Node.js application entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="index.js" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="node_modules" />
</hiddenSegments>
</requestFiltering>
</security>
<!-- You can control how Node is hosted within IIS using the following options -->
<!--<iisnode
node_env="%node_env%"
nodeProcessCountPerApplication="1"
maxConcurrentRequestsPerProcess="1024"
maxNamedPipeConnectionRetry="3"
namedPipeConnectionRetryDelay="2000"
maxNamedPipeConnectionPoolSize="512"
maxNamedPipePooledConnectionAge="30000"
asyncCompletionThreadCount="0"
initialRequestBufferSize="4096"
maxRequestBufferSize="65536"
watchedFiles="*.js"
uncFileChangesPollingInterval="5000"
gracefulShutdownTimeout="60000"
loggingEnabled="true"
logDirectoryNameSuffix="logs"
debuggingEnabled="true"
debuggerPortRange="5058-6058"
debuggerPathSegment="debug"
maxLogFileSizeInKB="128"
appendToExistingLog="false"
logFileFlushInterval="5000"
devErrorsEnabled="true"
flushResponse="false"
enableXFF="false"
promoteServerVars=""
/>-->
</system.webServer>
</configuration>
When I access my site Everything is working fine except that /getsomethings XHR is giving 404 error. All static contents are served fine.
Can anyone help me to figure out what is wrong?
You say "I am able to serve static contents to my users", because you have this in web.config.
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}" />
</rule>
Based on the code you provided above, please make sure your folder structure looks like:
D:\home\site
├── config
│ └── config.json
├── deployments
│ └── ...
├── locks
│ └── ...
├── Diagnostics
│ └── ...
├── public
│ └── dist
│ └── ...
└── wwwroot
├── node_modules
│ └── ...
├── index.js
├── package.json
└── web.config
Also, Please try changing the following line of code:
httpServer.listen(config.PORT);
to:
httpServer.listen(process.env.PORT || config.PORT);
I'm trying to enable GZip compress for SVG in an Azure Web Site using web.config transforms without success. Here is what my transform looks like:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.webServer>
<httpCompression>
<staticTypes>
<add mimeType="image/svg+xml" enabled="true" xdt:Transform="Insert" />
</staticTypes>
</httpCompression>
<staticContent xdt:Transform="Insert">
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
</staticContent>
</system.webServer>
</configuration>
This should both add the mime type for SVG, which Azure doesn't seem to have, and then enable compression. I've verified the mime type addition works fine, but upon publishing I get an error for the compression elements:
No element in the source document matches
'/configuration/system.webServer/httpCompression/staticTypes'
Removing the compression from the transform and adding it directly to my web.config file removes the error, but I still don't see the compression in the HTTP headers. Here are the response headers:
Accept-Ranges:bytes
Content-Length:23265
Content-Type:image/svg+xml
Date:Mon, 10 Jun 2013 17:19:37 GMT
ETag:"c4e9ec93d765ce1:0"
Last-Modified:Mon, 10 Jun 2013 12:39:41 GMT
Server:Microsoft-IIS/8.0
X-Powered-By:ASP.NET
X-Powered-By:ARR/2.5
X-Powered-By:ASP.NET
Here is how you can enable it in your web.config:
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
</staticContent>
<httpCompression>
<staticTypes>
<remove mimeType="*/*" />
<add mimeType="image/svg+xml" enabled="true" />
<add mimeType="*/*" enabled="false" />
</staticTypes>
</httpCompression>
</system.webServer>
</configuration>
The key line is the removal of the catch-all (and later re-add). If you don't have that, then the svg line basically gets ignored since the catch-all is inherited from applicationhost.config, and catches all before it reaches svg line.
Unfortunately it isn't possible to use built-in http compression on Azure Websites for image/xml+svg mime types. You have to change some IIS settings to do that which is possible if you're using Azure Web Roles.
I didn't want to go through that hassle however so I just made a controller in MVC to handle .svg files.
[AttributeRouting.RoutePrefix("static")]
public class ContentController : Controller
{
[GET(#"fonts/{fileName:regex(^[\w-\.]+\.svg$)}")]
[Compress, OutputCache(
Duration = 3600 * 24 * 30,
Location = OutputCacheLocation.Any,
VaryByContentEncoding = "gzip;deflate",
VaryByParam = "fileName")]
public ActionResult SvgFont(string fileName)
{
var path = Server.MapPath("~/Content/fonts/" + fileName);
if (!System.IO.File.Exists(path)) return HttpNotFound();
return File(path, "image/svg+xml");
}
}
public class CompressAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.CompressResult();
}
}
public static class HttpContextExtensions
{
public static bool CompressResult(this HttpContextBase context)
{
var request = context.Request;
var response = context.Response;
if (request == null || response == null) return false;
var filter = response.Filter;
if (filter is GZipStream || filter is DeflateStream) return false;
var acceptEncoding = (request.Headers["Accept-Encoding"] ?? string.Empty).ToLowerInvariant();
if (acceptEncoding.Contains("gzip"))
{
response.Filter = new GZipStream(filter, CompressionMode.Compress);
response.AddHeader("Content-Encoding", "gzip");
response.AppendHeader("Vary", "Content-Encoding");
return true;
}
if (acceptEncoding.Contains("deflate"))
{
response.Filter = new DeflateStream(filter, CompressionMode.Compress);
response.AddHeader("Content-Encoding", "deflate");
response.AppendHeader("Vary", "Content-Encoding");
return true;
}
return false;
}
}
You will also need to add this to your Web.config file so that MVC will handle routes with a .svg extension
<system.webServer>
<handlers>
<add name="StaticMvcHandler" path="static/fonts/*.svg" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
I have the following configuration entries for an Azure Web-Site:
<system.webServer>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
</system.webServer>
and
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<!-- Scalable Vector Graphics iPhone, iPad -->
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
I have added the .svgz extension as well (for compressed svg).
The above solution worked for me but I first had to remove the file extension. After that I got the results I was looking for.
<staticContent>
<remove fileExtension=".svg" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
</staticContent>
I have been trying to get the DELETE requests in my ASP.net WebAPI(ASP.net web role) working on Azure and locally on my machine.But end up getting "not found" error.
I have following configuration for the web.config of the ASP.net WebAPI web role:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit"
path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness32"
responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness64"
responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0"
path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
For making it work on IISExpress, I changed the $:\Users\\Documents\IISExpress\config\applicationhost.config configuration and commented out the WebDav portions of it and added the "PUT,DELETE" verbs appropriately.
To test my WebAPI I created a simple windows forms (.net 4.5 ) c# application and used the httpclient as below:
const string key = "user1";
var client = new HttpClient { BaseAddress = new Uri("http://abcd.cloudapp.net/") };
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var requestUrl = string.Format("api/user/{0}", key);
var deleteAsync = client.DeleteAsync(requestUrl).Result;
The response I get it following:
{StatusCode: 404,
ReasonPhrase: 'Not Found',
Version: 1.1,
Content: System.Net.Http.StreamContent,
Headers:
{
Pragma: no-cache
Cache-Control: no-cache
Date: Fri, 12 Apr 2013 06:40:31 GMT
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 128
Content-Type: application/json; charset=utf-8
Expires: -1
}} System.Net.Http.HttpResponseMessage
How do I get it to work on Azure? and possibly on my local machine as well.
I use this web.config:
<traceAreas>
<add provider="ASP" verbosity="Verbose" />
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
<add provider="ISAPI Extension" verbosity="Verbose" />
<add provider="WWW Server" areas="Security" verbosity="Verbose" />
</traceAreas>
<failureDefinitions statusCodes="200-999" />
And in webrole.cs
public override bool OnStart()
{
//Get Default Config
DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();
//IIS Logs
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
Trace.WriteLine("WAD Monitor started", "Information");
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);
RoleEnvironment.Changing += RoleEnvironmentChanging;
return base.OnStart();
}
I can get wad-iis-logsfiles blob, but I can't get wad-iis-failedreqlogfiles blob on my emulator
Why since 200-999 include all request!
And should have a log files.
Well, what I did is to set up my settings in the WebRole file and the code that I added to my web.config are this configurations
<system.diagnostics>
<trace>
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
</listeners>
</trace>
</system.diagnostics>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<tracing>
<traceFailedRequests>
<add path="*">
<traceAreas>
<add provider="ASP" verbosity="Verbose" />
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
<add provider="ISAPI Extension" verbosity="Verbose" />
<add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module" verbosity="Verbose" />
</traceAreas>
<failureDefinitions verbosity="Warning" statusCodes="400-599" />
</add>
</traceFailedRequests>
</tracing>
</system.webServer>
And then I implement the method Onstart with this configurations.
public override bool OnStart()
{
String wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));
RoleInstanceDiagnosticManager roleInstanceDiagnosticManager = cloudStorageAccount.CreateRoleInstanceDiagnosticManager(
RoleEnvironment.DeploymentId,
RoleEnvironment.CurrentRoleInstance.Role.Name,
RoleEnvironment.CurrentRoleInstance.Id);
DiagnosticMonitorConfiguration config = roleInstanceDiagnosticManager.GetCurrentConfiguration();
//Add Events
config.WindowsEventLog.DataSources.Add("System!*");
config.WindowsEventLog.DataSources.Add("Application!*");
config.WindowsEventLog.ScheduledTransferLogLevelFilter = LogLevel.Error;
config.WindowsEventLog.ScheduledTransferPeriod =TimeSpan.FromSeconds(15.0);
config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
config.Logs.ScheduledTransferPeriod = TimeSpan.FromSeconds(15.0);
//transfer the IIS and IIS Failed Request Logs
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
roleInstanceDiagnosticManager.SetCurrentConfiguration(config);
return base.OnStart();
}
And also I recommend you to check your ConnectionString on your WerRole settings, it should look something like this:
"DefaultEndpointsProtocol=http;AccountName=myAccount;AccountKey=8zTMPlQ8N76cEUNGLYhIvPf8lDmmTnCm7BICX/xtPmdr9vN7elOvZS5N2njtg+tbStoCoe30doN0sCrE1LHcsd=="
or
"UseDevelopmentStorage=true"
If you want to work on your development enviroment
Also you can take a look to this site for more details
http://robindotnet.wordpress.com/2011/02/16/azure-toolssdk-1-3-and-iis-logging/
Finally I found the answer!
This is because IIS applicationHost auto disable the trace log file.
When I add this code to webrole.cs and input a invalid url it works!
using (ServerManager serverManager = new ServerManager())
{
Configuration iisConfig = serverManager.GetApplicationHostConfiguration();
ConfigurationSection sitesSection = iisConfig.GetSection("system.applicationHost/sites");
ConfigurationElement siteDefaultsElement = sitesSection.GetChildElement("siteDefaults");
ConfigurationElement logFileElement = siteDefaultsElement.GetChildElement("logFile");
logFileElement["enabled"] = true;
serverManager.CommitChanges();
}