View Engines for Web Matrix Web Pages - asp.net

Microsoft has a new website editing tool: WebMatrix. WebMatrix uses the new Web Pages engine in which Razor is the view engine; Razor is also the new view engine for MVC3. I am attempting to find out if it is possible to register and use a different view engine in Web Pages (like you can in MVC).
Does anyone know if it is possible to add or replace the view engine in Web Pages? If so has anyone documented this? Examples?

I'm hoping to try this myself a bit later, but for now I'll just share my current thoughts:
In WebPages, Razor works by registering a BuildProvider with the ASP.NET build pipe for .cshtml and .vbhtml.
WebPages, in turn, registers the .cshtml .vbhtml extensions to its handler.
When a webPages page is requested, System.Web.WebPages.WebPageHttpHandler passes the path to the build pipe, where the extensions are matched with the registered Razor Provider, which renders the page and passes back a WebPage object, which handler passes to IIS and is served up.
You'll see all this if you use a reflection tool. Both of these are achieved in the PreApplicationStartCode.Start() of the corresponding assembly.
Razor hooking its build provider:
public static void Start()
{
if (!_startWasCalled)
{
_startWasCalled = true;
BuildProvider.RegisterBuildProvider(".cshtml", typeof(RazorBuildProvider));
BuildProvider.RegisterBuildProvider(".vbhtml", typeof(RazorBuildProvider));
}
}
WebPages hooking the WebPageHandler
public static void Start()
{
if (!_startWasCalled)
{
_startWasCalled = true;
WebPageHttpHandler.RegisterExtension("cshtml");
WebPageHttpHandler.RegisterExtension("vbhtml");
PageParser.EnableLongStringsAsResources = false;
DynamicModuleUtility.RegisterModule(typeof(WebPageHttpModule));
ScopeStorage.CurrentProvider = new AspNetRequestScopeStorageProvider();
}
}
To override we'd need to create and register a separate BuildProvider with the ASP.NET pipe to render our pages. System.Web.WebPages provides a WebPageHttpHandler.RegisterExtension() method which in theory you can hook a different BuildProvider to which will get the WebPage request instead of Razor.
Several blogs mention the RegisterExtension method, but there is also an open connect bug report showing it doesn't work 100%. It may be more appropriate to just override everything and hook our buildprovider to the pipe (not using the method).
Web.config provides a construct to register buildProviders, so I'll prob try that.
<buildProviders>
<add extension=".cshtml" type="CustomStuff.CustomBuildProvider"/>
</buildProviders>
The challenge is that most of the view engines out there use ViewEngines.Register(), a concept that webPages does not appear to have. So we'd have to wrap those view engines in a BuildProvider and/or create a BuildProvider that can successfully invoke IViewEngine
Again, just sharing my thinking. I'll try to register Spark or something later if I find some time.

You can't "register" view engines in Web Pages in the same way as MVC. You just mix and match file types. There's nothing to stop you adding .aspx files to your Web Pages site. Web Pages is much more akin to a Web Site project in VS.

Related

Why can't we use *.cshtml files as custom error pages now that (v4.7) we have "Razor Web Pages"?

B"H
Trying to revamp my global error handling, and running into the mess that is ASP.net error handlers.
I would really like to consolidate my solution as much as possible. So if possible I'd like to use the same pages to display from httpErrors and customErrors. I'd also like to use the appropriate Layout pages if possible. But it seems that if I want to use some kind of dynamic page as a custom error page that it needs to be *.aspx. Why is that? Especially now that we have Razor Web Pages?
PS. This is for an MVC (.net v4.7 ie not asp core) Site
If you are using the .cshtml file as a Razor Web Page, then can't you give the URL of the file, excluding the .cshtml? As per the table here: https://learn.microsoft.com/en-us/aspnet/core/mvc/razor-pages/?tabs=visual-studio
A standalone .cshtml file is will normally depend on a Code behind file (if using Razor Web Pages) or a MVC Controller Action to provide it with its data. I guess this is why you are not allowed to redirect directly to one.

One custom handler for different request url's in ASP.NET web site

I am doing a small ASP.NET 2.0. site refactoring.
Currently there is the following folder structure:
/siteroot/services/home/service1
/siteroot/services/home/service2
/siteroot/services/home/service3
...
all the folders (service1, 2, 3) contain an almost identical default.aspx, with the different content hardcoded into the web form declaration.
My idea is to create one service.aspx and serve custom page (with the same template) on a particular URL request.
My question is:
How can I redirect all request to ../services/home/service1,2,3 to one particular handler/aspx page?
Preferably not to have those folders in the project structure at all, but intercept a requests that are headed to them.
If you are able to implement ASP.NET 3.5 (runs on the 2.0 CLR), then Routing sounds perfect for what you need to achieve. With this you can intercept URLs based on a particular format and then route them through to a single page or handler. You won't need a folder structure for each of your services.
Here's a few links on how to get going with it in ASP.NET WebForms. It's pretty quick to implement:
http://msdn.microsoft.com/en-us/magazine/dd347546.aspx
http://msdn.microsoft.com/en-us/library/cc668201%28v=VS.90%29.aspx
http://haacked.com/archive/2008/03/11/using-routing-with-webforms.aspx
http://weblogs.asp.net/scottgu/archive/2009/10/13/url-routing-with-asp-net-4-web-forms-vs-2010-and-net-4-0-series.aspx
One way:
Create a custom handler class that implements IHttpModule
In Init(HttpApplication application), register a method for application.AuthorizeRequest
In this method, parse ((HttpApplication)sender).Request.Path as appropriate, using HttpContext.Current.RewritePath if necessary to point to a "real" service.aspx page.
Then register your custom handler in <system.webServer><modules>.
Another way is to use the MVC-style routing, which works without MVC just fine. Details are in the answer to the question here: custom URL Routing in asp.net.

How common usage are Page Methods in ASP.NET 4?

How common usage are Page Methods in ASP.NET 4?
I would like an example of how it's used (not a code sample).
I don't know about how common, but check out this example: http://aspalliance.com/1922_PageMethods_In_ASPNET_AJAX.all
Use page methods if you don't want to publicly expose a web service, and creating a web method that's specifically only to that page, IMHO. So for instance, I need web service features for one page only, that's when I create a page method. If I need something reusable in two pages, but don't want to publically expose it, I create a helper and the web method wraps the helper.
Otherwise, if you are looking to create a dynamic web site and share information, go with a traditional ASMX or WCF service.
HTH.
In your ASPX file you'll need this line.
<asp:ScriptManager ID="ScriptManager" runat="server" EnablePageMethods="true" />
In your code behind define a method marked as a WebMethod.
[WebMethod]
public static void MyMethod()
{
//code.....
Then to call that method in JavaScript.
PageMethods.SendForm(SuccessCallBack, FailureCallBack);
There are more advanced examples out there - just Google it.
I don't know about usage, but this is a very basic and clear example.

Site Security/Access management for asp.net mvc application

I am trying to find a good pattern to use for user access validation.
Basically on a webforms application I had a framework which used user roles to define access, ie, users were assigned into roles, and "pages" were granted access to a page. I had a table in the database with all the pages listed in it. Pages could have child pages that got their access inherited from the parent.
When defining access, I assigned the roles access to the pages. Users in the role then had access to the pages. It is fairly simple to manage as well. The way I implemented this was on a base class that every page inherited. On pageload/init I would check the page url and validate access and act appropriately.
However I am now working on a MVC application and need to implement something similar, however I can't find a good way to make my previous solution work. Purely because I don't have static pages as url paths. Also I am not sure how best to approach this as I now have controllers rather then aspx pages.
I have looked at the MVCSitemapprovider, but that does not work off a database, it needs a sitemap file. I need control of changing user persmissions on the fly.
Any thoughts/suggestions/pointers would be greatly appreciated.
When you create an MVC application, not the blank website, there is a basic ASP.NET Membership provider included. That will do everything you are looking for, with little to no coding.
Here is MSDN: http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx
Here is a CodePlex project that expands the functionality more than what was built in: http://mvcmembership.codeplex.com/
Your technique is easily accomplished by creating your own ActionFilter:
http://msdn.microsoft.com/en-us/library/dd410056.aspx
You can then apply this attribute to controllers or action methods and roll your own page security very easily.
public class MinmalSecurity : ActionFilterAttribute
{
private string _roles;
public MinmalSecurity(string roles)
{
_roles = roles;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//go to database,find permissions, redirect or proceed as nescessary
base.OnActionExecuting(filterContext);
}
}

Is there a recommended ASP.NET 2.0 method to serve HTML snippets via XHR to the client?

Here is my desired flow:
A static web page (html) uses XHR calls to an ASP.NET page
The .NET page retrieves information from a remote server using web services
The .NET page returns an HTML "snippet" that is inserted into the static HTML page
I'm getting hung up on how to deal with the HTML snippet generation on the .NET (2.0) page. I've thought about something like this in a generic .ashx page:
public void ProcessRequest (HttpContext context)
{
context.Response.Write("<ul>");
//assume "people" is a list of data coming from the external web service
foreach (string person in people)
{
context.Response.Write("<li>" + person + "</li>");
}
context.Response.Write("</ul>");
}
It just seems a big "ugly". Has anyone done this another - and possibly more efficient/elegant - way? Any help would be appreciated.
Returning html for this task is a bit weird, IMO. In most times I prefer the following way. Open your web service to public or add a wrapper to it and just use it directly from js of your static page. The service should return json (preferable) or xml data. On the client side format (print in html as you want) received data using js in callback to the XHR and inject anywhere you want.
But also I want to cast YAGNI on this task - if it'll be used only several times and in a few pages, use the most fastest way to implement it. But if you are building some RIA application I recommend you to check ExtJS javascript library.
Edit 26/02:
If you can't use ASP.NET MVC but wanna to use some good framework instead of "Response.Write" stuff please check OpenRasta. It's one of my favorite web frameworks. It works fine on .Net 2.0 and it's very flexible and powerful. And also it has a great community.

Resources