How to Response.Write on IIS7.5? - asp.net

i am trying to write out a response to the client:
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.ClearContent();
response.Write(String.Format(
"<!doctype html>"+CRLF+
"<html>" + CRLF +
"<head><title>{0}</title></head>" + CRLF +
"<body><h1>{0}</h1>"+CRLF+
"{1}"+CRLF+
"</body>" + CRLF +
"</html>",
response.Status, "The grob must be in the frobber."));
response.Flush();
response.End();
The code works fine when running on the localhost (Visual Studio (2010 (Windows 7 (Professional (64-bit))))) development Cassini web-server:
HTTP/1.1 400 Bad Request
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 17 Jul 2012 15:56:42 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: private
Content-Type: text/html
Connection: Close
<!doctype html>
<html>
<head><title>400 Bad Request</title></head>
<body><h1>400 Bad Request</h1>
The grob must be in the frobber.
</body>
</html>
But when i deploy the web-site to Windows Server 2008 R2 running IIS7.5, the same code doesn't work:
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 17 Jul 2012 15:57:44 GMT
Content-Length: 11
Bad Request
How do i perform Response.Write from IIS?

By default, IIS 7 will change the response if the code is >= 400
http://msdn.microsoft.com/en-us/library/ms690497(v=vs.90).aspx
But you can change this in the httpErrors element of system.webServer.
<httpErrors existingResponse="PassThrough" />
EDIT: this will break CustomErrors, if you are using that. You might be better off returning a 400 without a response, then setting up web.config to redirect to a custom page for 400 errors.
<customErrors mode="On">
<error statusCode="400" redirect="Frobber.htm" />
</customErrors>

I ran into this exact issue & spent a few frustrating hours today noodling through it. In my case, I am sending potentially very large CSV data directly down to the client via Response.Write and flushing it every 3k records or so. It works great from my local environment, but failed when deployed to IIS 7.5 on a Windows 2008 server. No exceptions, just an empty CSV at the client.
Turns out Dynamic Compression was enabled for my application. It can be disabled via web.config directly, or in your IIS MMC interface. You can validate this by using your browser's tools to examine the headers of the response you're receiving.
Content-Encoding:gzip
Disable dynamic compression (not sure how/why it was enabled originally), and it worked fine. It might not be your issue, but it was mine. I fished around for most of the day on this one and didn't see it answered directly, so I figured I'd throw it out there. Also, the size of the result set didn't matter; a 5kb file & 3Gb file had the same problem.

Have you checked that asp.net is enabled on the server? You need to use the Windows server manager to check the features have been installed.
I've just tried your code on my server & despite what I assume is a typo around casing of response, it worked as expected.

Related

Why does my Web API return 404 on all resources when called from a Console app?

I have a little Web API, almost directly from the standard VS project template, i.e. Home and Values controllers, and lots of MVC cruft. It is set to run and debug under IIS 10.
I have set up tracing by adding the package Microsoft.AspNet.WebApi.Tracing and the following code in WebApiConfig:
public static void Register(HttpConfiguration config)
{
config.EnableSystemDiagnosticsTracing();
SystemDiagnosticsTraceWriter traceWriter = config.EnableSystemDiagnosticsTracing();
traceWriter.IsVerbose = true;
traceWriter.MinimumLevel = TraceLevel.Debug;
config.Services.Replace(typeof(ITraceWriter), new SimpleTracer());
...
...
}
SimpleTracer is an ITraceWriter that writes to a text file.
When I call the API from outside the VS ecosystem, i.e. from PostMan in Chrome, a bad url, that results in a 404 error message, and the creation of a new trace file if there's not already one. Of I call it from PostMan with a good url, I get the expected result, and a trace of the request in the trace file.
When I call it from my Console app, even with a good url, I still get a 404 error response, and nothing is written to the trace file. I made sure by removing it and IIS doesn't even re-create it when using the .exe client.
If I call it from the compiled .exe from outside VS, I get the same error.
Then, when I set the Web API to use IIS Express, everything works perfectly. Do I need CORS for calls from non-web apps, does IIS need an extra header in this case? What is wrong?
EDIT A: This is the request when I use PostMan, and it returns a 200 and the expected list of strings.
GET /DemoApi/api/values HTTP/1.1
Host: localhost
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: f9454ffc-6a8d-e1ed-1a28-23ed8166e534
and the response and headers:
["value1","value2","value3","value4","value5","value6","value7"]
Cache-Control →no-cache
Content-Length →64
Content-Type →application/json; charset=utf-8
Date →Tue, 13 Dec 2016 06:20:07 GMT
Expires →-1
Pragma →no-cache
Server →Microsoft-IIS/10.0
X-AspNet-Version →4.0.30319
X-Powered-By →ASP.NET
EDIT B: This is the request sent using HttpClient:
GET http://abbeyofthelema/api/values HTTP/1.1
Accept: application/json
Host: abbeyofthelema
Connection: Keep-Alive
The only real difference is that because Fiddler doesn't capture traffic from localhost, I had to use my computer name instead. The same recipient still gets the request.
The response here is:
HTTP/1.1 404 Not Found
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Tue, 13 Dec 2016 08:07:25 GMT
Content-Length: 4959
According to Timothy Shields at the following link
Why is HttpClient BaseAddress not working?
You must place a slash at the end of the BaseAddress, and you must not place a slash at the beginning of your relative URI

SignalR 2.2 returns 404 Not Found on IIS 8.5

I've publish my Web-Api2 on a development server (Windows 2012 Server and IIS8.5).
I've added the Websockets Protocol role, and also went through the steps in this answer to make sure everything is set up on my side. The app is running under `Default Web Site'.
However, I'm still getting this error:
Microsoft.AspNet.SignalR.Client.HttpClientException: StatusCode: 404,
ReasonPhrase: 'Not Found', Version: 1.1, Content:
System.Net.Http.StreamContent, Headers:
{
Date: Fri, 15 Jul 2016 09:18:54 GMT
Server: Microsoft-IIS/8.5
X-Powered-By: ASP.NET
Content-Length: 1285
Content-Type: text/html
}
at Microsoft.AspNet.SignalR.Client.Http.DefaultHttpClient
<>c__DisplayClass2.<Get>b__1(HttpResponseMessage responseMessage)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2
<Then>b__17(Task`1 t)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.TaskRunners`2
<>c__DisplayClass42.<RunTask>b__41(Task`1 t)
Do I need to add other server roles or configure IIS further?
The problem was on the client side of the application as shown from here Microsoft.AspNet.SignalR.Client.HttpClientException
The status code was 404 Not Found.
The problem was a wrong url passed to the hub connection after deploying from localhost to an actual IIS running in Windows 2012 server. Once the url was fixed, the client runs without problems.

401 error when using a web service in sapui5

I am implementing a web service into my sapui5 table by
var oModel = new sap.ui.model.odata.ODataModel("http://mywebservice.com/security.svc", false);
sap.ui.getCore().setModel(oModel);
When I launch my code in a web browser and inspect element, I am getting the following errors:
Failed to load resource: the server responded with a status of 401 (Unauthorized)
XMLHttpRequest cannot load http://mywebservice.com/security.svc/$metadata. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:53457' is therefore not allowed access. The response had HTTP status code 401.
I also tested it in Fiddler and I get:
HTTP/1.1 401 Unauthorized
Cache-Control: private
Server: Microsoft-IIS/8.0
Set-Cookie: ASP.NET; path=/; HttpOnly
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Tue, 09 Jun 2015 19:33:51 GMT
Content-Length: 0
Proxy-Support: Session-Based-Authentication
Any help on how to fix the 401 error would be greatly appreciated.
Creating a new ODataModel, it tries to fetch the metadata for the service you have called.
It's basically XMLHttpRequest to a different domain(http://mywebservice.com) than you page(localhost) is on.So the browser is blocking it as it usually allows a request in the same origin for security reasons. Read about same-origin policy
Solution:
You need to do something different when you want to do a cross-domain request.
the origin (where the page with JavaScript is at) and the target: http://mywebservice.com (where the JavaScript is trying to reach) domains must be the exact same.
A tutorial about how to achieve that is Using CORS.
In .NET server,you can configure this in web.config as below
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" />
</customHeaders>
</httpProtocol>
<system.webServer>
Just clone the shortcut for chrome on your desktop, and then in the shortcut properties add the parameter --disable-web-security at the end of chrome executable path
e.g
"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-web-security
NB:add that parameter --disable-web-security in Target location after one space

Programatically updating a VSTO Word Addin in IIS7.5

We have recently moved to a new web server (from IIS6 to IIS7.5) and I'm having some trouble updating our VSTO word addin.
Our app checks for updates manually when logging in and if a newer version has been found updates like this (let me know if there is a better way to do this - I've tried ApplicationDeployment.Update() but had no luck with it either!):
WebBrowser browser = new WebBrowser();
browser.Visible = false;
Uri setupLocation = new Uri("https://updatelocation.com/setup.exe");
browser.Url = setupLocation;
This used to launch the setup and update the app and when the user restarted word they would have the new version installed. Since the server move the update no longer happens. No exceptions are thrown. Browsing to the URL launches the updater as expected. What would I need to change to get this to work?
Note I have the following MIME types setup on the folder in IIS:
.application
application/x-ms-application
.manifest
application/x-ms-manifest
.deploy
application/octet-stream
.msu
application/octet-stream
.msp
application/octet-stream
.exe
application/octet-stream
Edit
OK I've had a look in fiddler and its returning a body size of -1:
If I enter the same URL in IE you can see that the setup.exe is launched without problems.
This is what fiddler displays in the raw view when accessing from word:
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Last-Modified: Tue, 27 Sep 2011 15:07:42 GMT
Accept-Ranges: bytes
ETag: "9bd0c334277dcc1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Mon, 14 Nov 2011 07:42:18 GMT
Content-Length: 735608
MZ��������������������#������������������������������������������ �!�L�!This program cannot be run in DOS mode. $�������
*** FIDDLER: RawDisplay truncated at 128 characters. Right-click to disable truncation. ***
Have you tried a tool like (for instance) fiddler2 to see what http traffic is actually created?
Does the client make a server call? What does the server actually return?
Then:
Make the calls from within word (which isn't working)
Make the calls by hand (which is working)
Compare both the request and response packages from those calls to spot the differences

Asp.net http handler text file download issue. Works fine for codebehined

Recently we are encountering strange issue with file download http handler developed using C# 4.0.
The web application is developed using ASP.NET 4.0 and hosted on IIS 7.0 over ssl. It worked correctly. But recently due to some changes else where in config or website we are facing the issue listed below.
When we download the text file it emits junk data. The same file works fine if i use code behind on aspx page instead of handler. Both have same code. Some of the files works fine. for e.g. image file or pdf file works fine. But with text file the behavior is very inconsistent. Blank text file works fine. I tried comparing the two responses (handler vs codebehind) and it seems that content-length returned is not same.
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.ClearContent();
context.Response.ContentType = !String.IsNullOrEmpty(mime) ? mime : "application/octet-stream";
context.Response.AppendHeader("Content-Disposition", String.Format("attachment; filename={0}", fileName));
//context.Response.AppendHeader("Content-Length", buffer.Length.ToString());
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.End();
CODE BEHIND
HTTP/1.1 200 OK Server: ASP.NET Development Server/10.0.0.0 Date: Thu,
06 Oct 2011 02:52:26 GMT X-AspNet-Version: 4.0.30319
Content-Disposition: attachment; filename=my junk.txt Cache-Control:
private Content-Type: text/plain Content-Length: 29 Connection: Close
This is for sample test only
HTTPHANDLER
HTTP/1.1 200 OK Server: ASP.NET Development Server/10.0.0.0 Date: Thu,
06 Oct 2011 02:54:04 GMT X-AspNet-Version: 4.0.30319
Content-Disposition: attachment; filename=my junk.txt Cache-Control:
private Content-Type: text/plain Content-Length: 146 Connection: Close
��������I�%&/m�{J�J��t��$ؐ#������iG#)���eVe]f#�흼��{���{���;�N'���?\fdl��J�ɞ!���?~|?"�yѤ��N�l��͛6������ ������I���
Try to use AddHeader() instead of AppendHeader() and invoke Flush() before context.Response.End() statement.
Another thing you may want to do is surround the file name in quotes. Chrome/Opera do not handle this code correctly when the file name has a comma in it and think there are duplicate response headers.
context.Response.AddHeader("Content-disposition", string.Format("attachment; filename=\"{0}\""), fileName);
See here, here, and here for more information.

Resources