Last active
August 29, 2015 14:14
-
-
Save kpmrafeeq/dc742ed9c52d71ab464a to your computer and use it in GitHub Desktop.
DD4TFormHelper with BeginDD4TForm html extension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class DD4TFormHelper | |
{ | |
/// <summary> | |
/// | |
/// </summary> | |
/// <param name="html"></param> | |
/// <param name="action"></param> | |
/// <param name="controllerName"></param> | |
/// <param name="area"></param> | |
/// <param name="additionalRouteVals"></param> | |
/// <param name="htmlAttributes"></param> | |
/// <param name="method"></param> | |
/// <returns></returns> | |
public static MvcForm BeginDD4TForm(this HtmlHelper html, string action, string controllerName, string area, | |
object additionalRouteVals, | |
IDictionary<string, object> htmlAttributes, | |
FormMethod method) | |
{ | |
var formAction = HttpContext.Current.Request.Url.PathAndQuery; | |
return html.RenderForm(formAction, method, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), controllerName, action, area, additionalRouteVals); | |
} | |
/// <summary> | |
/// Helper method to create a new form to execute in the DD4T request pipeline against a locally declared controller | |
/// </summary> | |
/// <param name="html"></param> | |
/// <param name="action"></param> | |
/// <param name="controllerName"></param> | |
/// <param name="method"></param> | |
/// <returns></returns> | |
public static MvcForm BeginDD4TForm(this HtmlHelper html, string action, string controllerName, FormMethod method) | |
{ | |
return html.BeginDD4TForm(action, controllerName, null, new Dictionary<string, object>(), method); | |
} | |
/// <summary> | |
/// Helper method to create a new form to execute in the DD4T request pipeline against a locally declared controller | |
/// </summary> | |
/// <param name="html"></param> | |
/// <param name="action"></param> | |
/// <param name="controllerName"></param> | |
/// <param name="additionalRouteVals"></param> | |
/// <param name="htmlAttributes"></param> | |
/// <param name="method"></param> | |
/// <returns></returns> | |
public static MvcForm BeginDD4TForm(this HtmlHelper html, string action, string controllerName, | |
object additionalRouteVals, | |
IDictionary<string, object> htmlAttributes, | |
FormMethod method) | |
{ | |
return html.BeginDD4TForm(action, controllerName, "", additionalRouteVals, htmlAttributes, method); | |
} | |
public static string DecryptWithMachineKey(this string value) | |
{ | |
if (value == null) | |
return null; | |
string[] parts = value.Split('\n'); | |
StringBuilder decryptedValue = new StringBuilder(); | |
foreach (var part in parts) | |
{ | |
decryptedValue.Append(FormsAuthentication.Decrypt(part.TrimEnd()).UserData); | |
} | |
return decryptedValue.ToString(); | |
} | |
private static MvcForm RenderForm(this HtmlHelper htmlHelper, | |
string formAction, | |
FormMethod method, | |
IDictionary<string, object> htmlAttributes, | |
string controller, | |
string action, | |
string area, | |
object additionalRouteVals = null) | |
{ | |
//ensure that the multipart/form-data is added to the html attributes | |
if (htmlAttributes.ContainsKey("enctype") == false) | |
{ | |
htmlAttributes.Add("enctype", "multipart/form-data"); | |
} | |
var tagBuilder = new TagBuilder("form"); | |
tagBuilder.MergeAttributes(htmlAttributes); | |
// action is implicitly generated, so htmlAttributes take precedence. | |
tagBuilder.MergeAttribute("action", formAction); | |
// method is an explicit parameter, so it takes precedence over the htmlAttributes. | |
tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true); | |
var traditionalJavascriptEnabled = htmlHelper.ViewContext.ClientValidationEnabled && htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled == false; | |
if (traditionalJavascriptEnabled) | |
{ | |
// forms must have an ID for client validation | |
tagBuilder.GenerateId("form" + Guid.NewGuid().ToString("N")); | |
} | |
htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag)); | |
//new DD4TForm: | |
var theForm = new DD4TForm(htmlHelper.ViewContext, controller, action, area, method, additionalRouteVals); | |
if (traditionalJavascriptEnabled) | |
{ | |
htmlHelper.ViewContext.FormContext.FormId = tagBuilder.Attributes["id"]; | |
} | |
return theForm; | |
} | |
internal class DD4TForm : MvcForm | |
{ | |
/// <summary> | |
/// Creates an DD4TForm | |
/// </summary> | |
/// <param name="viewContext"></param> | |
/// <param name="controllerName"></param> | |
/// <param name="controllerAction"></param> | |
/// <param name="area"></param> | |
/// <param name="method"></param> | |
/// <param name="additionalRouteVals"></param> | |
public DD4TForm( | |
ViewContext viewContext, | |
string controllerName, | |
string controllerAction, | |
string area, | |
FormMethod method, | |
object additionalRouteVals = null) | |
: base(viewContext) | |
{ | |
_viewContext = viewContext; | |
_method = method; | |
_encryptedString = CreateEncryptedRouteString(controllerName, controllerAction, area, additionalRouteVals); | |
} | |
private readonly ViewContext _viewContext; | |
private readonly FormMethod _method; | |
private bool _disposed; | |
private readonly string _encryptedString; | |
protected override void Dispose(bool disposing) | |
{ | |
if (this._disposed) | |
return; | |
this._disposed = true; | |
_viewContext.Writer.Write("<input name='tprt' type='hidden' value='" + _encryptedString + "' />"); | |
base.Dispose(disposing); | |
} | |
} | |
internal static string CreateEncryptedRouteString(string controllerName, string controllerAction, string area, object additionalRouteVals = null) | |
{ | |
//need to create a params string as Base64 to put into our hidden field to use during the routes | |
var routeParams = string.Format("c={0}&a={1}&ar={2}", | |
HttpUtility.UrlEncode(controllerName), | |
HttpUtility.UrlEncode(controllerAction), | |
area); | |
var additionalRouteValsAsQuery = additionalRouteVals != null ? additionalRouteVals.ToDictionary<object>().ToQueryString() : null; | |
if (additionalRouteValsAsQuery.IsNullOrWhiteSpace() == false) | |
routeParams += "&" + additionalRouteValsAsQuery; | |
return routeParams.EncryptWithMachineKey(); | |
} | |
internal static IDictionary<string, TVal> ToDictionary<TVal>(this object o, params string[] ignoreProperties) | |
{ | |
if (o != null) | |
{ | |
var props = TypeDescriptor.GetProperties(o); | |
var d = new Dictionary<string, TVal>(); | |
foreach (var prop in props.Cast<PropertyDescriptor>().Where(x => !ignoreProperties.Contains(x.Name))) | |
{ | |
var val = prop.GetValue(o); | |
if (val != null) | |
{ | |
d.Add(prop.Name, (TVal)val); | |
} | |
} | |
return d; | |
} | |
return new Dictionary<string, TVal>(); | |
} | |
/// <summary> | |
/// Encrypt the string using the MachineKey in medium trust | |
/// </summary> | |
/// <param name="value">The string value to be encrypted.</param> | |
/// <returns>The encrypted string.</returns> | |
public static string EncryptWithMachineKey(this string value) | |
{ | |
if (value == null) | |
return null; | |
string valueToEncrypt = value; | |
List<string> parts = new List<string>(); | |
const int EncrpytBlockSize = 500; | |
while (valueToEncrypt.Length > EncrpytBlockSize) | |
{ | |
parts.Add(valueToEncrypt.Substring(0, EncrpytBlockSize)); | |
valueToEncrypt = valueToEncrypt.Remove(0, EncrpytBlockSize); | |
} | |
if (valueToEncrypt.Length > 0) | |
{ | |
parts.Add(valueToEncrypt); | |
} | |
StringBuilder encrpytedValue = new StringBuilder(); | |
foreach (var part in parts) | |
{ | |
var encrpytedBlock = FormsAuthentication.Encrypt(new FormsAuthenticationTicket(0, string.Empty, DateTime.Now, DateTime.MaxValue, false, part)); | |
encrpytedValue.AppendLine(encrpytedBlock); | |
} | |
return encrpytedValue.ToString().TrimEnd(); | |
} | |
public static string ToQueryString(this IDictionary<string, object> d) | |
{ | |
if (!d.Any()) return ""; | |
var builder = new StringBuilder(); | |
foreach (var i in d) | |
{ | |
builder.Append(String.Format("{0}={1}&", HttpUtility.UrlEncode(i.Key), i.Value == null ? string.Empty : HttpUtility.UrlEncode(i.Value.ToString()))); | |
} | |
return builder.ToString().TrimEnd('&'); | |
} | |
public static bool IsNullOrWhiteSpace(this string str) | |
{ | |
return (str == null) || (str.Trim().Length == 0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment