问题
I have managed to get TWO responses for a single web request:
- My webapi response ( a simple string with 200 status code)
- a 404, from what looks like a static file handler
Screenshot from chrome:
My setup is:
- F#
- Mono on Ubuntu 15.10
- xsp4 as the web server
- Owin as the routing engine
As you can see from the screenshot the correct response is printed (sometimes - sigh) on the first line of the browser's reponse, and then immediately followed on the page by the standard 404 page.
Startup code:
type Startup() =
static member RegisterWebApi(config: HttpConfiguration) =
// Configure routing
config.MapHttpAttributeRoutes()
// Configure serialization
config.Formatters.XmlFormatter.UseXmlSerializer <- true
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver <- Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
member __.Configuration(builder: IAppBuilder) =
let config = new HttpConfiguration()
Startup.RegisterWebApi(config)
builder.UseWebApi(config) |> ignore
builder.UseErrorPage() |> ignore
Controller code:
[<RoutePrefix("api")>]
type WordsearchController() =
inherit ApiController()
[<Route("")>]
member this.Get() =
this.Request.CreateResponse<string>(HttpStatusCode.OK, "This is my simple output")
I have tried removing the static file handler in the web.config, using MVC style route mapping in startup, and various routing attributes for the controller.
It just seems like both the webapi routing and the static file handler are BOTH putting their two cents into the reponse, instead of one overriding the other.
As per request from @mark, the request is a simple GET to http://localhost:9000/api, and the response is:
HEADER
HTTP/1.0 404 Not Found
Date: Mon, 18 Jan 2016 00:11:17 GMT
Server: Mono.WebServer.XSP/4.2.0.0 Linux
X-AspNet-Version: 4.0.30319
Content-Length: 5085
Cache-Control: private
Content-Type: text/html
Keep-Alive: timeout=15, max=94
Connection: Keep-Alive
BODY
GET api
404 Not Found
localhost:9000
5.0 KB
127.0.0.1:9000
2ms
HeadersResponseHTMLCache
<string>This is my simple output</string><?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional
.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
body { background-color: #FFFFFF; font-size: .75em; font-family: Verdana, Helvetica, Sans-Serif; margin
: 0; padding: 0; color: #696969; }
a:link { color: #000000; text-decoration: underline; }
a:visited { color: #000000; }
a:hover { color: #000000; text-decoration: none; }
a:active { color: #12eb87; }
p, ul { margin-bottom: 20px; line-height: 1.6em; }
pre { font-size: 1.2em; margin-left: 20px; margin-top: 0px; }
h1, h2, h3, h4, h5, h6 { font-size: 1.6em; color: #000; font-family: Arial, Helvetica, sans-serif; }
h1 { font-weight: bold; margin-bottom: 0; margin-top: 0; padding-bottom: 0; }
h2 { font-size: 1em; padding: 0 0 0px 0; color: #696969; font-weight: normal; margin-top: 0; margin-bottom
: 20px; }
h2.exceptionMessage { white-space: pre; }
h3 { font-size: 1.2em; }
h4 { font-size: 1.1em; }
h5, h6 { font-size: 1em; }
#header { position: relative; margin-bottom: 0px; color: #000; padding: 0; background-color: #5c87b2
; height: 38px; padding-left: 10px; }
#header h1 { font-weight: bold; padding: 5px 0; margin: 0; color: #fff; border: none; line-height: 2em
; font-family: Arial, Helvetica, sans-serif; font-size: 32px !important; }
#header-image { float: left; padding: 3px; margin-left: 1px; margin-right: 1px; }
#header-text { color: #fff; font-size: 1.4em; line-height: 38px; font-weight: bold; }
#main { padding: 20px 20px 15px 20px; background-color: #fff; _height: 1px; }
#footer { color: #999; padding: 5px 0; text-align: left; line-height: normal; margin: 20px 0px 0px 0px
; font-size: .9em; border-top: solid 1px #5C87B2; }
#footer-powered-by { float: right; }
.details { font-family: monospace; border: solid 1px #e8eef4; white-space: pre; font-size: 1.2em; overflow
: auto; padding: 6px; margin-top: 6px; background-color: #eeeeff; color: 555555 }
.details-wrapped { white-space: normal }
.details-header { margin-top: 1.5em }
.details-header a { font-weight: bold; text-decoration: none }
p { margin-bottom: 0.3em; margin-top: 0.1em }
.sourceErrorLine { color: #770000; font-weight: bold; }
</style>
<script type="text/javascript">
var hideElementsById = new Array ();
window.onload = function () {
if (!hideElementsById || hideElementsById.length < 1)
return;
for (index in hideElementsById)
toggle (hideElementsById [index]);
}
function toggle (divId)
{
var e = document.getElementById (divId);
if (!e)
return;
var h = document.getElementById (divId + "Hint");
if (e.style.display == "block" || e.style.display == "") {
e.style.display = "none";
if (h)
h.innerHTML = " (click to show)";
} else {
e.style.display = "block";
if (h)
h.innerHTML = " (click to hide)";
}
}
</script>
<title>Error 404</title>
</head>
<body>
<div class="page">
<div id="header">
<div id="header-text">Application Exception</div>
</div>
<div id="main">
<h1>System.Web.HttpException</h1>
<h2 class="exceptionMessage">The resource cannot be found.</h2>
<p><strong>Description:</strong> HTTP 404.The resource you are looking for (or one of its dependencies
) could have been removed, had its name changed, or is temporarily unavailable. Please review the following
URL and make sure that it is spelled correctly.</p><p><strong>Details:</strong> Requested URL: /api
</p>
<div><strong>Exception stack trace:</strong></div>
<div class="details"> at System.Web.StaticFileHandler.ProcessRequest (System.Web.HttpContext context
) <0x403b0a40 + 0x00733> in <filename unknown>:0
at System.Web.DefaultHttpHandler.BeginProcessRequest (System.Web.HttpContext context, System.AsyncCallback
callback, System.Object state) <0x403b0240 + 0x00153> in <filename unknown>:0
at System.Web.HttpApplication+<Pipeline>c__Iterator1.MoveNext () <0x40332110 + 0x04416>
; in <filename unknown>:0
at System.Web.HttpApplication.Tick () <0x40330c60 + 0x00057> in <filename unknown>:0 <
/div><div id="footer">
<div style="color:Black;"><strong>Version Information:</strong> <tt>4.2.1 (Stable 4.2.1.102/6dd2d0d
Thu Nov 12 09:52:44 UTC 2015)</tt>; ASP.NET Version: <tt>4.0.30319.17020</tt></div>
<div id="footer-powered-by">Powered by <a href="http://mono-project.com/">Mono</a></div>
</div>
</div>
</div>
</body>
</html>
<!--
[System.Web.HttpException]: Path '/api' was not found.
at System.Web.StaticFileHandler.ProcessRequest (System.Web.HttpContext context) <0x403b0a40 + 0x00733
> in <filename unknown>:0
at System.Web.DefaultHttpHandler.BeginProcessRequest (System.Web.HttpContext context, System.AsyncCallback
callback, System.Object state) <0x403b0240 + 0x00153> in <filename unknown>:0
at System.Web.HttpApplication+<Pipeline>c__Iterator1.MoveNext () <0x40332110 + 0x04416> in <filename
unknown>:0
at System.Web.HttpApplication.Tick () <0x40330c60 + 0x00057> in <filename unknown>:0
-->
1 request
5.0 KB
2ms (onload: 88ms)
回答1:
Mono does not support WebAPI async pipeline.
I make pull request for mono https://github.com/mono/mono/pull/3048. It makes Synchronous execution of asynchronous web api stack.
Now you may use WebAPI async pipeline with this fix for Mono.
来源:https://stackoverflow.com/questions/34834346/404-response-appended-to-webapi-response