Here's what you could try:
Start by designing each page you would like to have with its input fields. Then you could define the ViewModels, the Controllers and the corresponding Views. It might look something like this (oversimplified):
ViewModels:
/// <summary>
/// Represents a button with its text and
/// the controller name it will redirect to
/// </summary>
public class Button
{
public string Text { get; set; }
public string Controller { get; set; }
}
/// <summary>
/// Represents the page with a header and a list of buttons
/// </summary>
public class Page
{
public string Header { get; set; }
public IEnumerable<Button> Buttons { get; set; }
}
/// <summary>
/// Each view model will have page metadata
/// </summary>
public abstract class BaseViewModel
{
public Page Page { get; set; }
}
public class Page1ViewModel : BaseViewModel
{
// Put any properties specific to this page
// which will be used for the input fields
}
public class Page2ViewModel : BaseViewModel
{
// Put any properties specific to this page
// which will be used for the input fields
}
...
Then create a repository which will parse the XML (the implementation is left for brevity):
public interface IPagesRepository
{
Page ReadPage(string pageName);
}
Then here's how a page controller might look like:
public class Page1Controller : Controller
{
private readonly IPagesRepository _repository;
// TODO: to avoid repeating this ctor you could have
// a base repository controller which others derive from
public Page1Controller(IPagesRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
var model = new Page1ViewModel();
model.Page = _repository.ReadPage("page1");
//model.Page = new Page
//{
// Header = "Thanks for calling, how may I help you?",
// Buttons = new[]
// {
// new Button { Text = "Next", Controller = "Page2" },
// new Button { Text = "Address", Controller = "Page3" },
// }
//};
return View(model);
}
[HttpPost]
public ActionResult Index(Page1ViewModel model, string redirectTo)
{
if (!ModelState.IsValid)
{
return View(model);
}
return Redirect(redirectTo);
}
}
And the last part is the corresponding view:
<script type="text/javascript">
$(function () {
// when a navigation link is clicked set the redirectTo
// hidden field to the value of the controller we
// want to redirect to and submit the form
$('.nav a').click(function () {
$('form :hidden[name=redirectTo]').val(this.href);
$('form').submit();
return false;
});
});
</script>
<h2><%: Model.Page.Header %></h2>
<%: Html.ValidationSummary() %>
<% using (Html.BeginForm()) { %>
<%: Html.Hidden("redirectTo") %>
<!-- TODO: Put here the specific input fields for this page -->
<% } %>
<div class="nav">
<%: Html.EditorFor(x => x.Page.Buttons) %>
</div>
And the Button.ascx
Editor Template which will render the navigation links:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeNs.Models.Button>" %>
<!-- Here we assume Index action is setup by default in the routes -->
<%: Html.ActionLink(Model.Text, "index", Model.Controller) %>