I am developing an application using asp.net 2.0 (C#), in which I am trying to implement the compression of my files, so that performance of my website will improve.
For that I have added a code in my Global.asax file to compress all requests (.aspx, .js, .css) But when I am running my application it works well for first time then the CSS is not loading and web page is not rendering properly.
Why its happening??
Edited (added my compression code)
My compression code of Global.asax file is as follows:
void Application_BeginRequest()
{
HttpContext incoming = HttpContext.Current;
string oldpath = incoming.Request.Path.ToLower();
incoming.Response.Filter = new GZipStream(incoming.Response.Filter, CompressionMode.Compress);
HttpContext.Current.Response.AppendHeader("Content-encoding", "gzip");
HttpContext.Current.Response.Cache.VaryByHeaders["Accept-encoding"] = true;
}
Also please let me know if there is any other better way to do the same, using the Global.asax file, because I don't have access of IIS Settings and also I don't have permission to implement the HttpModule, that is why I am using Global.asax file.
Thanks
For static files, you can configure IIS to do the compression for you, no need to implement it yourself.
In IIS6 this is a global setting (properties of the "Web Sites" node in IIS manager, service tab).
In IIS7 this is set on a per folder basis, and it will also compress dynamic content for you. It can either be set in IIS Manager or in the web.config file:
<configuration>
<system.webServer>
<urlCompression doDynamicCompression="true" doStaticCompression="true" />
</system.webServer>
</configuration>
Related
I have a problem after implementing Owin and secured all controllers and webapi of a asp.net mvc site, using cookie and bearer token. All static files like javascripts , images and some html files are unsecured and can be downloaded without authorization.
So far I have tried to implement, staticfiles (using Microsoft.Owin.StaticFiles) and setting static files for a request path but without any sucess. For example this?
app.UseStaticFiles("/Scripts");
And I have tried , using web.config settings like this wich is mentiond in katana documentation, but from this point to lets say roleX should have access to imagesX and roleY to imageY ? nothing is mention in the documentation about that or even how to control the files.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
So question is how do i secure static files using owin and authorization cookie.
Do i have to write a own middle ware , checking each request if it is a static file, or is there any recomended package on nuget that solves this?
OWIN way of doing this would be with some middleware. New asp.net core will not support web.config and modules. Just be sure to plugin your auth middleware before static file middleware. It really depends what's your authentication and authorization framework of choice, but you can check an example here: https://coding.abel.nu/series/owin-authentication/
I have this in my web.config:
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="UserFiles"/>
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
I think I am going about this the wrong way, but I can't seem to find the right way to google this. I want to grant download access to only that folder 'UserFiles'. I need to do this via the web.config since the live environment will be on Azure, so I will not have a machine to RDP into to change this is IIS.
First, if you are using Azure web role and not Azure Websites, you should be storing this stuff in a blob. Second, are these files needing to be secured so that only authenticated users can access them (or even users can only access their own files?).
Lets assume that anyone can download any file from the server. If that is the case, create a directory called UserFiles underneath content. Now, you can simply link to those files like so
MY File title
Now, if they are secured behind an authentication scheme, things get tricky. You don't want just anyone to be able to download those items. So, lets take a few steps to secure them.
1.Create a folder called UserFiles at the top level of your solution.
2.In your web.config, let's make it to where no one can access it
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="UserFiles"/>
</hiddenSegments>
</requestFiltering>
</security>
3.Create a MVC controller, lets call it files, that you actually will use to deliver the files to the user. In here, let's make an action called download that takes in a file Id (assuming you are storing file information in the database)
public FileResult Download(int id){
//perform logic to see if user has access to this file
//if access, return the file
//else return a 404
}
Now, your file download link will look like
#Html.ActionLink("My File Title", "Download", "Files", new{id = Model.Id})
MVC and your code will have access to the UserData folder, while an outside web user will not. Use the controller/action to gate your content
Files in App_Data will not be served to the end user, by design.
App_Data is used to store data files. From the MSDN:
App_Data contains application data files including .mdf database files, XML
files, and other data store files. The App_Data folder is used by
ASP.NET to store an application's local database.
The content of application folders... is not served in
response to Web requests, but it can be accessed from application code.
It would be pretty bad if people could download stuff, like your database, out of App_Data.
You'll need to move the UserFiles folder outside of App_Data.
I am trying to build a webservice that manipulates http requests POST and GET.
Here is a sample:
public class CodebookHttpHandler: IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.Request.HttpMethod == "POST")
{
//DoHttpPostLogic();
}
else if (context.Request.HttpMethod == "GET")
{
//DoHttpGetLogic();
}
}
...
public void DoHttpPostLogic()
{
...
}
public void DoHttpGetLogic()
{
...
}
I need to deploy this but I am struggling how to start. Most online references show making a website, but really, all I want to do is respond when an HttpPost is sent. I don't know what to put in the website, just want that code to run.
Edit:
I am following this site as its exactly what I'm trying to do.
I have the website set up, I have the code for the handler in a .cs file, i have edited the web.config to add the handler for the file extension I need. Now I am at the step 3 where you tell IIS about this extension and map it to ASP.NET. Also I am using IIS 7 so interface is slightly different than the screenshots. This is the problem I have:
1) Go to website
2) Go to handler mappings
3) Go Add Script Map
4) request path - put the extension I want to handle
5) Executable- it seems i am told to set aspnet_isapi.dll here. Maybe this is incorrect?
6) Give name
7) Hit OK button:
Add Script Map
Do you want to allow this ISAPI extension? Click "Yes" to add the extension with an "Allowed" entry to the ISAPI and CGI Restrictions list or to update an existing extension entry to "Allowed" in the ISAPI and CGI Restrictions list.
Yes No Cancel
8) Hit Yes
Add Script Map
The specified module required by this handler is not in the modules list. If you are adding a script map handler mapping, the IsapiModule or the CgiModule must be in the modules list.
OK
edit 2: Have just figured out that that managed handler had something to do with handlers witten in managed code, script map was to help configuring an executable and module mapping to work with http Modules. So I should be using option 1 - Add Managed Handler.
I know what my request path is for the file extension... and I know name (can call it whatever I like), so it must be the Type field I am struggling with. In the applications folder (in IIS) so far I just have the MyHandler.cs and web.config (Of course also a file with the extension I am trying to create the handler for!)
edit3: progress
So now I have the code and the web.config set up I test to see If I can browse to the filename.CustomExtension file:
HTTP Error 404.3 - Not Found
The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.
So in IIS7 I go to Handler Mappings and add it in. See this MSDN example, it is exactly what I am trying to follow
The class looks like this:
using System.Web;
namespace HandlerAttempt2
{
public class MyHandler : IHttpHandler
{
public MyHandler()
{
//TODO: Add constructor logic here
}
public void ProcessRequest(HttpContext context)
{
var objResponse = context.Response;
objResponse.Write("<html><body><h1>It just worked");
objResponse.Write("</body></html>");
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
I add the Handler in as follows:
Request path: *.whatever
Type: MyHandler (class name - this appears correct as per example!)
Name: whatever
Try to browse to the custom file again (this is in app pool as Integrated):
HTTP Error 500.21 - Internal Server Error
Handler "whatever" has a bad module "ManagedPipelineHandler" in its module list
Try to browse to the custom file again (this is in app pool as CLASSIC):
HTTP Error 404.17 - Not Found
The requested content appears to be script and will not be served by the static file handler.
Direct Questions
1) Does the website need to be in CLASSIC or INTEGRATED mode? I don't find any reference of this in the online material, whether it should be either.
2) Do I have to compile the MyHandler.cs to a .dll, or can I just leave it as .cs? Does it need to be in a bin folder, or just anywhere in root?
RE your questions:
I don't know the answer to the first one (CLASSIC or INTEGRATED); but I can help with the second...
Yes you'll need to compile it first. I have never tried deploying dll's to anywhere other than the bin, given that that's the standard I would be suspect in putting them anywhere else even if it did work.
The way I deploy HttpHandlers is quiet straight forward - all the hard work's done in web.config, I'v enever had to go into IIS to change any settings.
For a start, for the http request to be handled by ASP.NET you need to use a request suffix that's already piped to ASP.NET - like .aspx or ashx. If you want to use something else you will need to config IIS to do this, as per your managed handler img above.
I tend to use .ashx e.g: http://localhost/foo/my/httphandler/does/this.ashx
All you need to do (assuming you've compiled athe HttpHandler into a DLL and deployed it to the site) is add the necessary config.
<configuration>
<system.web>
<httpHandlers>
<add verb="*"
path="*.ashx"
type="MyApp.PublishingSystem.HttpHandlers.GroovyHandler, MyApp.PublishingSystem" />
</httpHandlers>
</system.web>
</configuration>
Obviously (?) you can change / restrict the scope using the path, e.g:
path="*.ashx"
path="*ListWidgets.ashx"
path="*Admin/ListWidgets.ashx"
More info here: http://msdn.microsoft.com/en-us/library/ms820032.aspx
An important gotcha to look out for is the order in which you declare your HttpHandlers in the config; from what I remember ones declared first take precedent. So in this example...
<add verb="*" path="*foo.ashx" type="MyApp.PublishingSystem.HttpHandlers.FooHandler, MyApp.PublishingSystem" />
<add verb="*" path="*.ashx" type="MyApp.PublishingSystem.HttpHandlers.GroovyHandler, MyApp.PublishingSystem" />
...the groovy handler will handle all HttpRequests except any that end in foo.ashx
By the way, I make use of HttpHanldrs in my open source .net CMS / app framework, you might find some helpful code there (?): http://morphfolia.codeplex.com/
Make sure the app pool's .NET Framework Version is set correctly...
I deployed a .NET 4.0 web app on a .NET 2.0 app pool and got this error. Set the app pool to v4.X and the ashx was served like a champ.
I have a ASP .NET load balanced application (webservice and website). It runs on SQL server. I need to be able to provide large files for download. However, because of the load balancing situation, the files are stored in the SQL database as opposed to the file system. BITS seems to be the best approach. I have full control of the client. However, i don't know how to configure BITS to read the file from the database. I know how to write the C# code for that, but i don't know how to get BITS to hook into it as opposed to reading the file from the file system.
Any ideas?
You can create a custom http handler by implementing System.Web.IHttpHandler. The ProcessRequest(HttpContext context) method is where you will write your file retrieval code from the database. Since BITS operates with range requests you will need to parse the value of context.Request.Headers["Range"] to get the start and end bytes requested. In the ProcessRequest you can read the binary from the database using the SqlCommand.ExecuteReader(CommandBehavior.SequentialAccess) method and set the resulting binary in context.Response.OutputStream. Remember to call context.Response.Flush() at the end.
The custom HttpHandler will serve a particular file extension (e.g. '.file'). This is what needs to be done in IIS:
Both IIS Versions
Add to section in in web.config:
IIS 6.0
Add .file (application/x-zip-compressed) extension as MIME type for the website.
Add Application Extension (Website Properties Virtual Directory Configuration Mappings)
Extension: .file
Executable Path(s): %windir%\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll
%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll
IIS 7.0
Add to section in in web.config:
Add to section in in web.config:
<mimeMap fileExtension=".file" mimeType="application/x-zip-compressed" />
Hope that's enough to get you started.
Have a look at 2008 Books Online OpenSqlFilestream. That API has examples that may help you.
We have a web application where we are using global.asax for url rewriting. We use a compiled version of the site on the live server.
As a part of modification request, we had to add some custom native AJAX code where javascript would call a webservice to update the content of the page. For being able to call the webservice with extension .asmx, we modified the url rewriting code to handle asmx requests seperately.
this arrangement works fine on the local machine, but when we publish the site and deploy it on the live server, the new code doesnt seem to get included. It still skips the condition to check the ".asmx" extension, and throws a page not found exception considering the webservice name as a page name.
We have tried looking all over and googled for such things as well.. but no avail..
any pointers on what might be going wrong.. ?
Assuming your URL rewriting is good (isn't that normally implemented as a HttpModule?) I'd check to make sure that there's an ISAPI mapping in IIS on production that sends .asmx requests to ASP.NET.
If you think your changes to the global.asax haven't been rejitted then you can always stop the application pool, go find your web applications compiled bits in c:\windows\microsoft.net\framework[version]\temporary asp.net files... and delete the jitted version. I've seen ASP.NET miss when it comes to Jitting changes before.
I'd also consider running http fiddler (IE) or tamper data (FireFox extension) on one of the pages that makes calls to the web service. It will tell you exactly how the page is calling the web service and you can validate that the called URL is correct.
There is machine.config file where you can add HttpModules. I also think that you can do that through web.config.
One reason I can think of is that in the Web.config, you might have configured the routing module in the system.web section but not in system.webServer (or at least forgot something in there).
I the similar problem before and the solution was to remove the module & add it again in the system.webServer section of the Web.config like this:
<system.webServer>
<modules>
<remove name="UrlRoutingModule" />
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, e="RoleManager" type="System.Web.Security.RoleManagerModule"/>
</modules>
</system.webServer>
It might be a different module or handler but the idea is basically the same. It's important to "remove" the module first.