我有一个自定义路由处理程序,如下所示:
public class SkipstoneMvcHandler: MvcHandler, IRequiresSessionState
{
public SkipstoneMvcHandler(RequestContext requestContext)
: base(requestContext)
{
}
protected override IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state)
{
return base.BeginProcessRequest(httpContext, callback, state);
}
private ControllerBuilder _controllerBuilder;
internal ControllerBuilder ControllerBuilder
{
get
{
if (this._controllerBuilder == null)
{
this._controllerBuilder = ControllerBuilder.Current;
}
return this._controllerBuilder;
}
set
{
this._controllerBuilder = value;
}
}
private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
{
HttpContext current = HttpContext.Current;
string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
factory = this.ControllerBuilder.GetControllerFactory();
controller = factory.CreateController(this.RequestContext, requiredString);
if (controller == null)
{
throw new InvalidOperationException("Could not find the controller.");
}
}
protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
{
var companyId = CompanyProvider.CurrentCompanyId(); // Get our current company id
if (companyId != null)
{
var vpp = new SkipstoneVirtualPathProvider(); // Create an instance of our VirtualPathProvider class
var requestContext = ((MvcHandler)httpContext.Handler).RequestContext; // Get our request context
var path = requestContext.HttpContext.Request.Url.AbsolutePath; // Get our requested path
// If we have a path
if (path != null)
{
var pages = vpp.Pages; // Get all the published pages for this company
// If we have pages
if (pages != null)
{
var page = pages.Where(model => model.Path.ToLower() == path.ToLower()).SingleOrDefault(); // Select the page matching our requested path (if any)
if (page != null) // If we find the page
{
requestContext.RouteData.Values["area"] = page.Area; // Set the area
requestContext.RouteData.Values["controller"] = "Virtual" + page.Controller; // Set the controller
requestContext.RouteData.Values["action"] = page.Name; // And the action
}
}
}
}
return base.BeginProcessRequest(httpContext, callback, state);
}
protected override void ProcessRequest(HttpContext httpContext)
{
base.ProcessRequest(httpContext);
}
}
这一切都很好。在我的 VirtualControllers 中,我有类似的内容:
public async Task<ActionResult> Edit(string id)
{
var fileName = string.Empty;
using (var service = new PageService(new CompanyService(), User.Identity.GetUserId()))
{
fileName = await service.View(Request.Url);
}
using (var service = new UserService(new CompanyService(), User.Identity.GetUserId()))
{
var user = await service.FindByIdAsync(id);
ViewData["User"] = user;
}
if (!fileName.StartsWith(@"/"))
return View(fileName); // Show the page
else
return Redirect(fileName); // Redirect to our page
}
我更愿意:
我有一个基本控制器,如下所示:
public class VirtualBaseController : Controller
{
public async Task<ViewResult> View(string masterName, object model)
{
if (model != null)
{
base.ViewData.Model = model;
}
using (var service = new PageService(new CompanyService()))
{
var viewname = await service.View(Request.Url);
return this.View(viewname, masterName, model);
}
}
}
我在这里尝试做的是当在我的控制器中调用返回View()时,它继承自 VirtualBaseController 而不是寻找物理文件,它将会返回虚拟文件。