PortableRazor is a mobile framework that provides a lightweight implementation of ASP.NET MVC APIs along with a simple route handler. Combined, these features encapsulate the construction of hybrid-friendly URLs inside of a webview, and provide the hooks to intercept these URLs in order to call .NET code.
To learn the basics of how to use the Razor templating engine to build hybrid apps with C# and Xamarin, read Building HTML views using Razor Templates
For a complete sample app which leverages the features of PortableRazor, check out the PortableRazor Starter Kit
You can integrated PortableRazor into your mobile app in a few easy steps:
- First, reference the PortableRazor PCL project from your app, or from a compatible PCL project.
- Provide an implementation of PortableRazor's IHybridWebView in your native project. The IHybridWebView interface gives PortableRazor apps a platform-agnostic way to load HTML into a WebView, and to execute Javascript in WebView in the conext of the page. The PortableRazor Starter Kit includes reference implementations for iOS and Android
- Instantiate controllers to handle requests made inside your PortableRazor app, and register these with the PortableRazor's RouteHandler.
- Wire up the RouteHandler to intercept URL loading by your webview.
- Ensure that any pages that need to use PortableRazor helper methods include the
@inherits PortableRazor.ViewBase
directive at the top of the page.
PortableRazor includes an abstract ViewBase class which provide access to HTML and URL helper classes for generating action links to invoke methods in your controllers, and MVC Form elements, including CheckBox, Hidden, Password, RadioButton, TextArea, and TextBox input elements. These helpers can be accessed by using the Html and Url properties of the ViewBase.
A simple MVC Form that uses the PortableRazor framework might look like:
@inherits PortableRazor.ViewBase
@model SampleItem
<html>
<head>
<link rel="stylesheet" href="mystyle.css" />
<script src="myscript.js"></script>
</head>
<body>
@using (Html.BeginForm("SavePokemon")) {
<div>
@Html.ActionLink("Cancel", "ShowSampleItemList")
</div>
<div>
<h4>Item</h4>
@Html.Label("Name", "name")
@Html.TextBox("name", Model.Name, new { placeholder="Name" })
</div>
@Html.Hidden("number", Model.Number)
<input type="submit" data-icon="check" value="Save"/>
}
</body>
</html>
To use PortableRazor's route handler, you need to first implement controllers to handle interactions with your app's HTML views. Controller methods should be instance methods, and will typically render HTML to the HybridWebView using LoadHtmlString, or emit Javascript to be executed with the HybridWebView's EvaluateJavascript method.
Controllers can be implemented entirely in a PCL if all user interaction is platform agnostic (i.e., all interaction with the user can be handled by loading HTML or executing javascript in the webview), or can be implemented in the native project. A good option for apps that can be implemented entirely in HTML, but where a native implementation on some platforms might be preferable, is to first provide a complete implementation of the controller in the PCL, and then subclass the controller in the native project to override some functions with an alternative native implementation. (E.g., a PCL controller could support tweeting through a web interface, but use the native Twitter APIs in iOS to provide a better experience on that platform.)
When you initialize your app, you will need register an instance of your controller with the PortableRazor route handler:
PortableRazor.RouteHandler.RegisterController ("Politician", politicianController);
Links and HTML Forms generated by PortableRazor include a custom URL scheme, along with the name of the controller, method, and parameters that should be invoked when the link is followed, or the form is submitted.
When the native webview processes a navigation request, PortableRazor's RouteHandler process the request's target URL to determine if the request
can be handled by the registered controllers. On iOS, the request should be by handling the UIWebView’s HandleShouldStartLoad event
. In Android,
subclass the WebViewClient used in the form, and wire up HandleRequest in the ShouldOverrideUrlLoading
method.
bool handled = PortableRazor.RouteHandler.HandleRequest (request.Url.AbsoluteString);