//******************************************************************************************************
// RazorView.cs - Gbtc
//
// Copyright © 2016, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
// file except in compliance with the License. You may obtain a copy of the License at:
//
// http://opensource.org/licenses/MIT
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 01/13/2016 - J. Ritchie Carroll
// Generated original version of source code.
//
//******************************************************************************************************
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using GSF.Collections;
using GSF.Data;
using RazorEngine.Templating;
// ReSharper disable StaticMemberInGenericType
namespace GSF.Web.Model
{
///
/// Defines a view class for data context based Razor template implementations.
///
public class RazorView
{
#region [ Members ]
// Fields
private readonly IRazorEngine m_razorEngine;
private readonly DynamicViewBag m_viewBag = new DynamicViewBag();
private Dictionary m_parameters;
#endregion
#region [ Constructors ]
///
/// Creates a new .
///
/// instance to use.
/// Name of template file, typically a .cshtml or .vbhtml file.
/// Delegate to handle exceptions, if any.
public RazorView(IRazorEngine razorEngine, string templateName, Action exceptionHandler = null) : this(razorEngine, templateName, null, null, null, null, null, exceptionHandler)
{
}
///
/// Creates a new .
///
/// instance to use.
/// Name of template file, typically a .cshtml or .vbhtml file.
/// Reference to model to use when rendering template.
/// Type of .
/// Type of data class for views based on paged view model, if any.
/// Type of SignalR hub for views based on paged view model, if any.
/// to use, if any.
/// Delegate to handle exceptions, if any.
public RazorView(IRazorEngine razorEngine, string templateName, object model = null, Type modelType = null, Type pagedViewModelDataType = null, Type pagedViewModelHubType = null, AdoDataConnection database = null, Action exceptionHandler = null)
{
m_razorEngine = razorEngine;
TemplateName = templateName;
Model = model;
ModelType = modelType;
PagedViewModelDataType = pagedViewModelDataType;
PagedViewModelHubType = pagedViewModelHubType;
Database = database;
ExceptionHandler = exceptionHandler;
}
#endregion
#region [ Properties ]
///
/// Gets or sets name of template file.
///
public string TemplateName
{
get; set;
}
///
/// Gets or sets reference to model to use when rendering template.
///
public object Model
{
get; set;
}
///
/// Gets or sets type of .
///
public Type ModelType
{
get; set;
}
///
/// Gets or sets type of data model for views based on paged view model.
///
public Type PagedViewModelDataType
{
get; set;
}
///
/// Gets or sets type of SignalR hub for views based on paged view model.
///
public Type PagedViewModelHubType
{
get; set;
}
///
/// Gets reference to view bag used when rendering template.
///
public dynamic ViewBag => m_viewBag;
///
/// Gets query string parameter specified by .
///
/// Name of query string parameter to retrieve.
/// Query string parameter specified by .
public string this[string key] => Parameters[key];
///
/// Gets a dictionary of query string parameters passed to rendered view.
///
public Dictionary Parameters
{
get
{
if ((object)m_parameters == null)
{
HttpRequestMessage request = ViewBag.Request;
m_parameters = HttpUtility.ParseQueryString(request.RequestUri.Query).ToDictionary();
}
return m_parameters;
}
}
///
/// Gets reference to used by this .
///
public IRazorEngine RazorEngine => m_razorEngine;
///
/// Gets or sets database connection to provide to , if any.
///
public AdoDataConnection Database
{
get;
set;
}
///
/// Gets or sets delegate used to handle exceptions.
///
public Action ExceptionHandler
{
get; set;
}
///
/// Gets or sets to use for the provided to the view; defaults to null.
///
///
/// This should typically not be changed. When value is null, the data context will use the default
/// instance for which is used
/// to generate template based HTML input fields for a view. The default HTML input templates are defined
/// as embedded resources in GSF.Web.
///
public IRazorEngine DataContextEngine
{
get;
set;
}
#endregion
#region [ Methods ]
///
/// Compiles and executes view template.
///
/// Rendered result.
public string Execute()
{
using (DataContext dataContext = new DataContext(Database, razorEngine: DataContextEngine, exceptionHandler: ExceptionHandler))
{
if ((object)PagedViewModelDataType != null && (object)PagedViewModelHubType != null)
dataContext.ConfigureView(PagedViewModelDataType, PagedViewModelHubType, null as string, m_viewBag);
m_viewBag.AddValue("DataContext", dataContext);
return m_razorEngine.RunCompile(TemplateName, ModelType, Model, m_viewBag);
}
}
///
/// Compiles and executes view template for specified request message and post data.
///
/// HTTP request message.
/// trueif is HTTP post; otherwise, false.
/// Rendered result.
public string Execute(HttpRequestMessage request, bool isPost)
{
using (DataContext dataContext = new DataContext(Database, razorEngine: DataContextEngine, exceptionHandler: ExceptionHandler))
{
if ((object)PagedViewModelDataType != null && (object)PagedViewModelHubType != null)
dataContext.ConfigureView(PagedViewModelDataType, PagedViewModelHubType, request, m_viewBag);
m_viewBag.AddValue("DataContext", dataContext);
m_viewBag.AddValue("Request", request);
m_viewBag.AddValue("IsPost", isPost);
return m_razorEngine.RunCompile(TemplateName, ModelType, Model, m_viewBag);
}
}
///
/// Asynchronously compiles and executes view template for specified request message and post data.
///
/// HTTP request message.
/// trueif is HTTP post; otherwise, false.
/// Propagates notification from client that operations should be canceled.
/// Task that will provide rendered result.
public Task ExecuteAsync(HttpRequestMessage request, bool isPost, CancellationToken cancellationToken)
{
return Task.Run(() => Execute(request, isPost), cancellationToken);
}
#endregion
}
}