HttpModule class as follows:-
namespace WebApplication1
{
public class RewriterHttpModule : IHttpModule
{
public void Init(HttpApplication r_objApplication)
{
// Register our event handler with Application object.
r_objApplication.BeginRequest += new EventHandler(BeginRequest);
}
public void Dispose()
{
// Left blank because we dont have to do anything.
}
protected void BeginRequest(object r_objSender,
EventArgs r_objEventArgs)
{
// Authenticate user credentials, and find out user roles.
HttpApplication objApp = (HttpApplication)r_objSender;
HttpContext objContext = (HttpContext)objApp.Context;
string fullOrigionalpath = objContext.Request.Url.ToString();
if (fullOrigionalpath.Contains("/Default/Books.aspx"))
{
objContext.RewritePath("/Default.aspx?Category=Books");
}
else if (fullOrigionalpath.Contains("/Default/DVDs.aspx"))
{
objContext.RewritePath("/Default.aspx?Category=DVDs");
}
}
}
}
Web.Config file as follows:-
<configSections>
<section name="rewriter" requirePermission="false"
type="Intelligencia.UrlRewriter.Configuration.RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter" />
</configSections>
<add name="UrlRewriter" type="WebApplication1.RewriterHttpModule, WebApplication1"/>
</httpModules>
<rewriter>
<rewrite url="~/Default/books.aspx" to="~/Default.aspx?category=books"/>
<rewrite url="~/Default/CDs.aspx" to="~/Default.aspx?category=CDs" />
<rewrite url="~/Default/DVDs.aspx" to="~/Default.aspx?category=DVDs" />
</rewriter>
Sitemaster Page as follows:-
<head runat="server">
<title></title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
I have the url rewriting working alright but when the default.aspx page is loaded on the browser it is not styled by the css stylesheet. What could be the problem?
Check this link:
IIS Rewrite
And for css/javascript you must use absolute path, like:
<script src="../my.js"/><script>
will become
<script src="/js/my.js"/><script>
Something like that.
Forgot to explain.
Suppose in original link /default.aspx?Category=books
you have
When browser load the page it will look after /mystyle.css
When you put /default/books.aspx (that it will load default.aspx?Category=books)
the browser will look after /default/mystyle.css (but you do not have the default directory and mystyle.css in this directory).
Do nothing when requesting script folder like:
<if url="^/css/(.+)$">
<rewrite to="~/$1" processing="stop" />
</if>
or just add this to top of rewrite config
<rewrite url="^(/.+(\.gif|\.flv|\.swf|\.png|\.jpg|\.ico|\.pdf|\.doc|\.xls|\.css|\.zip|\.rar|\.js|\.xml|\.mp3)(\?.+)?)$" to="$1" processing="stop" />
i think your css path will be changed. have you checked by viewsource?
any way, applied the css in that way:
<link href='css/homepage.css' rel='stylesheet' type='text/css' />
hope this help.
Related
When I go to the root of my ASP.NET website, the request goes into the ASP.NET pipeline and then returns index.html.
Is there a way in web.config to configure this so that IIS simply returns the file without going into the ASP.NET pipeline?
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
<h1>Test</h1>
</body>
</html>
Global.asax:
using System.Web;
namespace Test
{
public class Global : HttpApplication
{
protected void Application_BeginRequest()
{
var url = this.Request.Url;
}
}
}
web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>
You can set runAllManagedModulesForAllRequests=false inside web.config. It has other side effects, but can give a try first.
<system.webServer>
<modules runAllManagedModulesForAllRequests="false" />
</system.webServer>
I've put together a very basic tutorial for a jQuery Mobile app with a very basic tutorial using the Web Api with VS 2013 and VB.NET. The Web Api is just for use with my UI within my app as a way to bridge between html and asp.net. It works perfectly on my development machine but the Web Api part fails when I move it to my hosting service (WinHost). I assume that there is a web.config entry that will fix this - but, I'm totally lost on this point. The html/jQuery code is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="css/custom.css" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-mobile/1.3.2/jquery.mobile.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" />
<title>Boilerplate</title>
<script>
var uri = 'api/class1s';
function formatItem(item) {
return item.field1;
}
function find() {
var id = $('#prodId').val();
$.getJSON(uri + '/' + id)
.done(function (data) {
$('#product').text(formatItem(data));
})
.fail(function (jqXHR, textStatus, err) {
$('#product').text('Error: ' + err);
});
}
</script>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Boilerplate</h1>
</div>
<div data-role="content">
<p>Page Body content</p>
<div>
<input type="text" id="prodId" size="5" />
<input type="button" value="Search" onclick="find();" />
<p id="product" />
</div>
</div>
<div data-role="footer">
<h4>Footer content</h4>
</div>
View Full Site
</div>
</body>
</html>
The web.config is:
<configuration>
<appSettings></appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</configuration>
There is also a WebApiConfig:
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web.Http
Public Module WebApiConfig
Public Sub Register(ByVal config As HttpConfiguration)
' Web API configuration and services
' Web API routes
config.MapHttpAttributeRoutes()
config.Routes.MapHttpRoute(
name:="DefaultApi",
routeTemplate:="api/{controller}/{id}",
defaults:=New With {.id = RouteParameter.Optional}
)
End Sub
End Module
There is also a class to define the data and a controller to populate data and return data via the Web Api.
These should not affect this problem (and work perfectly on my desktop PC).
Otherwise, this is just a standard VS2013 ASP.Net 4.5.1 project using an empty website with the Web Api option selected.
Is there a way to get this program to work on the hosting service?
I am tring to utilize a simple SignalR sample and from a reason I get the 404 code from the following -
<script src="<%= ResolveUrl("~/signalr/hubs") %>" type="text/javascript"></script>
I checked the SignalR documentation and changed my web.config according to what is suggests there still I get that 404 status code.
my code follows -
Web.Config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
<httpRuntime/>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
</modules>
</system.webServer>
</configuration>
Default.aspx:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR-0.5.3.min.js" type="text/javascript"></script>
<script src="<%= ResolveUrl("~/signalr/hubs") %>" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
//var connection = new Connection( "127.0.0.1");
// Proxy created on the fly
var chat = $.connection.chatt;
// Declare a function on the chat hub so the server can invoke it
chat.addMessage = function (message) {
$('#messages').append('<li>' + message + '</li>');
};
$("#broadcast").click(function () {
// Call the chat method on the server
chat.send($('#msg').val());
});
// Start the connection
$.connection.hub.start();
});
</script>
</head>
<input type="text" id="msg" />
<input type="button" id="broadcast" value="broadcast" />
<ul id="messages">
</ul>
</html>
Please assist.
I had this same problem, the solution is putting this in your Global.asax file:
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs();
}
Unfortunately this isn't documented anywhere, even though it's an essential part of SignalR configuration...
In case if error occurred on my web site I do the following:
Server.Transfer("/error.aspx");
and that page has code:
protected void Page_Load(object sender, EventArgs e)
{
...
Response.StatusCode = 404;
}
If I work on the localhost then together with 404 status returned for the page, page displays 'proper error description'.
Once I published the same code to the internet all pages with errors are still displayed with 404 status code, but the don't have the content. Instead, they have the standard 404 error message:
404 - File or directory not found.
if the line "Response.StatusCode = 404" commented out then the proper page is provided, but it has 200 status code.
Question: how to return user-friendly error page that in the same time has 404 error status code?
Any thoughts are welcome! Thanks a lot in advance!
P.S. ASP.NET 4.0
<customErrors mode="On" defaultRedirect="~/Error/GenericErrorPage.aspx">
<error statusCode="404" redirect="~/Error/404.aspx" />
</customErrors>
http://msdn.microsoft.com/en-us/library/h0hfz6fc(v=vs.71).aspx
http://msdn.microsoft.com/en-us/library/aa479319.aspx
A ha!
Try this:
Response.TrySkipIisCustomErrors = true;
Response.Status = "404 Not Found";
Response.StatusCode = 404;
I found as soon as I added Response.TrySkipIisCustomErrors=true before setting the status code, I would see the normal page copy AND a 404 is returned. Without this line the standard IIS 404 page is displayed.
Alternatively, this can be set in the web.config like so:
<system.webServer>
<httpErrors existingResponse="PassThrough">
// custom error page mappings
</httpErrors>
</system.webServer>
The key thing here is existingResponse="PassThrough"
This was added to IIS7 thus is required on sites running in Integrated Pipeline mode.
For more info: http://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomerrors.aspx
Update
Updating for clarrification/more info as people are still finding this useful.
It's worth noting that if you need a simple, generic 404 page use the web.config method (and best make it a plain HTML page).
The method I describe works best if you have a heavily dynamic or CMS driven site where any given page could potentially return a 404 but you want to show your visitor related info.
For example, a special offers page (offers/some-offer) could do a lookup for the offer (some-offer) and if it doesn't exist show alternative or related offers while returning a 404 under the bonnet. As far as the visitor is aware they've just been told the offer is no longer available but they're still in the offers section but we're also telling robots to un-index the URL.
This would be a lot harder to do if there was just one generic 404 page.
You can achieve this by configuring your web.config file. Please check the link below to an article, which explains at the bottom of the page, how to display different custom error pages for different HTTP error statuses.
Displaying a Custom Error Page
To show your own page with the correct 404 statuscode, you can use the following code:
1) In your web.config add the following:
<customErrors mode="On" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="404.htm" />
</customErrors>
and:
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="404.htm" responseMode="File"/>
</httpErrors>
2) Add a 404.htm file to the root of your website:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>404 - Not Found</title>
<meta http-equiv="refresh" content="5;url=/404-PAGE" />
</head>
<body>
CONTENT
</body>
</html>
You can either add content to the body of this file and remove the META refresh or simply use the META refresh to open a page within your CMS.
Combining Jag's and adt's answers, I still had a problem. When a 404 was handled by the static file handler (as opposed to ASP.NET), I got a blank response. (The status was correctly 404.)
To fix it, I had to add errorMode="Custom" to the <httpErrors> element. If your error page uses ASP.NET, you need to include responseMode="ExecuteURL".
<system.web>
<customErrors mode="On" defaultRedirect="~/Error.aspx" redirectMode="ResponseRewrite" />
</system.web>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" />
<error statusCode="404" path="/Error.aspx" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="ErrorPages/error404.htm" responseMode="Redirect"/>
</httpErrors>
This works for me if I don't use the tilde (~) in the path attribute
For anyone wondering in ASPNET 6.0+ you can now use the following official solution [1]
In Program.cs:
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
In StatusCode.cshtml.cs
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
public int OriginalStatusCode { get; set; }
public string? OriginalPathAndQuery { get; set; }
[ViewData]
public string Code { get; set; } = "";
public void OnGet(int statusCode)
{
OriginalStatusCode = statusCode;
Code = statusCode.ToString();
var statusCodeReExecuteFeature =
HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature is not null)
{
OriginalPathAndQuery = string.Join(
statusCodeReExecuteFeature.OriginalPathBase,
statusCodeReExecuteFeature.OriginalPath,
statusCodeReExecuteFeature.OriginalQueryString);
}
}
}
In StatusCode.cshtml (here is where you can customize to your sites theme)
#page
#model StatusCodeModel
Its a Custom Page for Status Code: #ViewData["Code"]
[1] https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0#usestatuscodepageswithreexecute
To create & access 404 page in asp.net C# follow the steps:
1)create an 404.html file & add your content
<html>
<head>
<meta charset="utf-8" />
<title>404 - Not Found</title>
<link href="bootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<style>
body {
color: #797979;
background: #eaeaea;
font-family: 'Ruda', sans-serif;
padding: 0px !important;
margin: 0px !important;
font-size: 13px;
}
.p404 img {
margin-top: 120px;
}
.centered {
text-align: center;
}
.p404 h1 {
font-weight: 900;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-6 col-lg-offset-3 p404 centered">
<img src="assets/img/404.png" alt="">
<h1>DON'T PANIC!!</h1>
<h3>The page you are looking for doesn't exist.</h3>
<br>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<a class="btn btn-success" href="Default.aspx">Back To Home</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
in web config add this code
<system.web>
<customErrors mode="On" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="404.html" />
</customErrors>
</system.web>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="404.html" responseMode="File"/>
</httpErrors>
</system.webServer>
I have seen ASP.NET MVC Without Visual Studio, which asks,
Is it possible to produce a website based on ASP.NET MVC, without using Visual Studio?
And the accepted answer is, yes.
Ok, next question: how?
Here's an analogy. If I want to create an ASP.NET Webforms page, I load up my favorite text editor, create a file named Something.aspx. Then I insert into that file, some boilerplate:
<%# Page Language="C#"
Debug="true"
Trace="false"
Src="Sourcefile.cs"
Inherits="My.Namespace.ContentsPage"
%>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Title goes here </title>
<link rel="stylesheet" type="text/css" href="css/style.css"></link>
<style type="text/css">
#elementid {
font-size: 9pt;
color: Navy;
... more css ...
}
</style>
<script type="text/javascript" language='javascript'>
// insert javascript here.
</script>
</head>
<body>
<asp:Literal Id='Holder' runat='server'/>
<br/>
<div id='msgs'></div>
</body>
</html>
Then I also create the Sourcefile.cs file:
namespace My.Namespace
{
using System;
using System.Web;
using System.Xml;
// etc...
public class ContentsPage : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Literal Holder;
void Page_Load(Object sender, EventArgs e)
{
// page load logic here
}
}
}
And that is a working ASPNET page, created in a text editor. Drop it into an IIS virtual directory, and it's working.
What do I have to do, to make a basic, hello, World ASPNET MVC app, in a text editor? (without Visual Studio)
Suppose I want a basic MVC app with a controller, one view, and a simple model. What files would I need to create, and what would go into them?
ok, I examined Walther's tutorial and got a basic MVC site running.
The files required were:
Global.asax
App_Code\Global.asax.cs
App_Code\Controller.cs
Views\HelloWorld\Sample.aspx
web.config
That's it.
Inside the Global.asax, I provide this boilerplate:
<%# Application Inherits="MvcApplication1.MvcApplication" Language="C#" %>
And that MvcApplication class is defined in a module called Global.asax.cs which must be placed into the App_Code directory. The contents are like this:
using System.Web.Mvc;
using System.Web.Routing;
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{arg}", // URL with parameters
new { // Parameter defaults
controller = "HelloWorld",
action = "Index",
arg = "" } );
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
The Controller.cs provides the logic to handle the various requests. In this simple example, the controller class is like this:
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class HelloWorldController : Controller
{
public string Index()
{
return "Hmmmmm...."; // coerced to ActionResult
}
public ActionResult English()
{
return Content("<h2>Hi!</h2>");
}
public ActionResult Italiano()
{
return Content("<h2>Ciao!</h2>");
}
public ViewResult Sample()
{
return View(); // requires \Views\HelloWorld\Sample.aspx
}
}
}
The Controller class must be named XxxxxController, where the Xxxxx portion defines the segment in the URL path. For a controller called HelloWorldController, the URL path segment is HelloWorld. Each public method in the Controller class is an action; the method is called when that method name is included in another segment in the url path . So for the above controller, these URLs would result in invoking the various methods:
http:/ /server/root/HelloWorld (the default "action")
http:/ /server/root/HelloWorld/Index (same as above)
http:/ /server/root/HelloWorld/English
http:/ /server/root/HelloWorld/Italiano
http:/ /server/root/HelloWorld/Sample (a view, implemented as Sample.aspx)
Each method returns an Action result, one of the following: View (aspx page), Redirect, Empty, File (various options), Json, Content (arbitrary text), and Javascript.
The View pages, such as Sample.aspx in this case, must derive from System.Web.Mvc.ViewPage.
<%# Page Language="C#"
Debug="true"
Trace="false"
Inherits="System.Web.Mvc.ViewPage"
%>
That's it! Dropping the above content into an IIS vdir gives me a working ASPNET MVC site.
(Well, I also need the web.config file, which has 8k of configuration in it. All this source code and configuration is available to browse or download.)
And then I can add other static content: js, css, images and whatever else I like.
You would do exactly what you did above, because you wouldn't use a model or controller in a hello world app.
All visual studio does is provide you with file creation wizards, so in theory, all you need to do is create the right files. If you want detailed specifications for the MVC project structure, good luck, most documentation is written on the assumption you are using visual studio, but you might be able to go through a tutorial step by step, and puzzle it out.
Your best bet is to find a downloadable demo project, use visual studio to reverse engineer the project structure, or try one of the open source .net IDE.
Well, this is how the default VS skeleton for an MVC 1.x app looks like:
Content
Site.css
Controllers
AccountController.cs
HomeController.cs
Models
Scripts
(all the jquery scripts)
MicrosoftAjax.js
MicrosoftMvcAjax.js
Views
web.config
Account
ChangePassword.aspx
ChangePasswordSuccess.aspx
LogOn.aspx
Register.aspx
Home
About.aspx
Index.aspx
Shared
Error.aspx
LogOnUserControl.ascx
Site.master
Default.aspx
Global.asax
web.config
Dunno if that's what you're looking for... the key here is obviously the web.config file.
Note: if you added namespace you must have an assembly.
web.config example for Cheeso example project on opensuse linux under mono project.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="dotless" type="dotless.Core.configuration.DotlessConfigurationSectionHandler, dotless.Core" />
</configSections>
<appSettings>
<add key="webpages:Version" value="1.0.0.0" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<customErrors mode="Off"/>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<!-- <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> -->
</assemblies>
</compilation>
<authentication mode="None"></authentication>
<pages>
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<!-- <add namespace="System.Web.Helpers" />
<add namespace="System.Web.WebPages" /> -->
</namespaces>
</pages>
<httpHandlers>
<add path="*.less" verb="GET" type="dotless.Core.LessCssHttpHandler, dotless.Core" />
</httpHandlers>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<add name="dotless" path="*.less" verb="*" type="dotless.Core.LessCssHttpHandler,dotless.Core" resourceType="File" preCondition="" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Abstractions" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<dotless minifyCss="false" cache="true" web="false" />
</configuration>