submit complex model with prefix - asp.net-mvc

I'd like to know your opinion about this way used to submit complex models in MVC
For example, if I have a complex model like this:
public class TOIFormDTO
{
public TradeFormDTO Trade { get; set; }
public OrderFormDTO Order { get; set; }
public ItemFormDTO Item { get; set; }
public TOIFormDTO() {
Trade = new TradeFormDTO();
Order = new OrderFormDTO();
Item = new ItemFormDTO();
}
}
And, I bind it to the view in the form:
#using (Html.BeginForm("SaveTOI", "Item", FormMethod.Post, new {id = "FormTOI" }))
{
<div id="tabs" style="width:1100px; height:500px">
<ul>
<li>Trade</li>
<li>Order</li>
<li>Item</li>
</ul>
<fieldset>
<legend></legend>
<div id="tabTrade">
#Html.PartialForCustomPrefix(model => model.Trade, "~/Views/Trade/Trade.cshtml", "Trade")
</div>
<div id="tabOrder" style="display: none">
#Html.PartialForCustomPrefix(model => model.Order, "~/Views/Order/Order.cshtml", "Order")
</div>
<div id="tabItem">
#Html.PartialForCustomPrefix(model => model.Item, "~/Views/Item/Item.cshtml", "Item")
</div>
</fieldset>
</div>
}
By putting a prefix this way:
public static MvcHtmlString PartialForCustomPrefix<TModel, TProperty>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression, string partialViewName, string CustomPrefix)
{
object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
var viewData = new ViewDataDictionary(helper.ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo
{
HtmlFieldPrefix = CustomPrefix
}
};
return helper.Partial(partialViewName, model, viewData);
}
This way, when the form is submitted the model is correctly 'recognized' by the action:
public ActionResult SaveTOI(TOIFormDTO toiToSave)
{
}
Do you think this is a good way to procede, is it solid?
Or do you recognized some potential failure?

Related

Asp.net core MVC fetch image from DB based on the Category

I am sorry to bother with simple matters but i really cannot find a way out of this problem.
I am building a Gallery, which container different fields, one of those is Category.
Category Class is a public Enum, and i would like to retrieve all the images in the Database and display them in View based on my Category selection.
Here you can find the code that i wrote so far.
View:
<form method="get" asp-controller="Gallery" asp-action="index">
<div style="height:60px;" class="container">
<div class="row">
<div class="col-md-5">
<div class="row" style="padding-top:10px;">
<div class="col-md-5">
#Html.Editor("Name", new { htmlAttributes = new { #class = "form-control", placeholder = "Name..." } })
</div>
</div>
</div>
<div class="col-md-5">
<select class="custom-select form-control mr-sm-2" asp-items="Html.GetEnumSelectList<Category>()"></select>
</div>
<div class="col-md-1">
<div class="row" style="padding-top:10px; padding-right:20px;">
<button type="submit" name="submit" class="btn btn-success form-control" value="submit">
<i class="fas fa-search fa-1x"></i>
</button>
</div>
</div>
</div>
</div>
</form>
Controller:
public IActionResult Index(string Name, Category category)
{
var model = _galleryRepository.GetAllImages();
StringBuilder param = new StringBuilder();
param.Append("&Name=");
if (Name != null)
{
param.Append(Name);
}
if(Name != null)
{
model = _galleryRepository.SearchName(Name);
}
if(category != Category.All)
{
model = _galleryRepository.SearchCategory(category);
}
return View(model);
}
Model Category:
public enum Category
{
All,
Photography,
Portrait,
Nature
}
Model Gallery:
public class Gallery
{
public int Id { get; set; }
public int Like { get; set; }
public string Comment { get; set; }
[Required]
[MaxLength(40, ErrorMessage ="Name cannot exceed 40 characters")]
public string Name { get; set; }
[Required]
[MaxLength(100, ErrorMessage = "Description cannot exceed 100 characters")]
public string Description { get; set; }
[Required]
public Category Category { get; set; }
public string PhotoPath { get; set; }
}
I did Managed to create a search form based on the Name of the image and it works just fine. But when it come to retrieve the images based on the Category Selection, it does not work.
i used a breakpoint on the Controller on the If statment related to category, and i realized that the condition fires but the model inside no.
So i am asking to the expert for an explanation about how to fix it as it the first time that i work with Enum and retrieving datas based on Enum classes.
Thank you so much for your help and i hope i made clear my problem.
Change your view like below,then you could pass the selected item to category:
#model Gallery
<form method="get" asp-controller="Gallery" asp-action="index">
//...
<div class="col-md-5">
<select asp-for="Category" class="custom-select form-control mr-sm-2" asp-items="Html.GetEnumSelectList<Category>()"></select>
</div>
//...
</form>
The default model binder won't work with Enum types. Either you need to change the parameter to of type string and convert it to it's equivalent enum type before performing the comparisions OR provide your own implementation of model binder and override the default one. If I were you, I will go with the simplest solution like below,
public IActionResult Index(string Name, string selectedCategory)
{
var category = Enum.Parse(typeof(Category),selectedCategory,true);
var model = _galleryRepository.GetAllImages();
StringBuilder param = new StringBuilder();
param.Append("&Name=");
if (Name != null)
{
param.Append(Name);
}
if(Name != null)
{
model = _galleryRepository.SearchName(Name);
}
if(category != Category.All)
{
model = _galleryRepository.SearchCategory(category);
}
return View(model);
}

asp.net mvc viewmodel getting error public definition for getenumerator

I can get my Products model to my view ok. but I need to pass it in a ViewModel so I can interact with data from several models. When I bind my view to ProductPageViewModel then I get the "no public definition for GetEnumerator" error. I have tried all manner of IEnumerable options and cannot find the right combination.
I included controller and view that work when the view is bound to the model.
The full error is
CS1579: foreach statement cannot operate on variables of type JaniesWebLive.ViewModel.ProductPageViewModel' because
JaniesWebLive.ViewModel.ProductPageViewModel' does not contain a public definition for 'GetEnumerator'
Triggered at #foreach (var item in Model)
Products.cs
public class Products
{
[Key]
public int WpId { get; set; }
public string Category { get; set; }
public string WpProductId { get; set; }
public string ProdDescShort { get; set; }
public string ProdDescLong { get; set; }
public string ProductMedium { get; set; }
public decimal? Price1 { get; set; }
}
ProductPageViewModel.cs
public class ProductPageViewModel
{
public IEnumerable<Products> Products { get; set; }
public Contact Contacts { get; set; }
public string Message { get; set; }
/*more models to be added */
}
ProductsController.cs
public class ProductsController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
public ActionResult ShortList(string prodname)
{
var products = db.DbProducts.Where(m => m.Category == "homepage");
var model = new ViewModel.ProductPageViewModel
{
Products = products,
Message = "Thanks for your business! "
/* more models to be added */
};
return View(model);
}
}
ShortList.cshtml
#model IEnumerable<JaniesWebLive.ViewModel.ProductPageViewModel>
#foreach (var item in Model)
{
<div class="row">
<div class="col-md-4 col-sm-6 col-xs-12">
<p><img class="product-image" src=#Html.DisplayFor(modelItem => item.ProductMedium) /></p><br />
<h3>#Html.DisplayFor(modelItem => item.WpProductId)</h3>
<h5>#Html.DisplayFor(modelItem => item.Price1)</h5>
<h6>#Html.DisplayFor(modelItem => item.ProdDescShort)</h6>
<p class="text-center">#Html.DisplayFor(modelItem => item.ProdDescLong)</p>
<p>
<button class="text-right btn btn-link">SHORT LIST</button>
</p>
</div>
</div>
}
Working controller and view
public ActionResult LongList(string prodname)
{
var model = db.DbProducts.Where(m => m.Category == "homepage");
return View(model);
}
LongList.cshtml
#model JaniesWebLive.Models.Products
#foreach (var item in Model)
{
<div class="row">
<div class="col-md-4 col-sm-6 col-xs-12">
<p><img class="product-image" src=#Html.DisplayFor(modelItem => item.ProductMedium) /></p>
<h3>#Html.DisplayFor(modelItem => item.WpProductId)</h3>
<h5>#Html.DisplayFor(modelItem => item.Price1)</h5>
<h6>#Html.DisplayFor(modelItem => item.ProdDescShort)</h6>
<p class="text-center">#Html.DisplayFor(modelItem => item.ProdDescLong)</p>
<p>
<button class="text-right btn btn-link">LONG LIST</button>
</p>
</div>
</div>
}
you need to change the view to something like
#model JaniesWebLive.ViewModel.ProductPageViewModel
#foreach (var item in Model.Products )
{
<div class="row">
<div class="col-md-4 col-sm-6 col-xs-12">
<p><img class="product-image" src=#Html.DisplayFor(modelItem => item.ProductMedium) /></p><br />
<h3>#Html.DisplayFor(modelItem => item.WpProductId)</h3>
<h5>#Html.DisplayFor(modelItem => item.Price1)</h5>
<h6>#Html.DisplayFor(modelItem => item.ProdDescShort)</h6>
<p class="text-center">#Html.DisplayFor(modelItem => item.ProdDescLong)</p>
<p>
<button class="text-right btn btn-link">SHORT LIST</button>
</p>
</div>
</div>
}
since upr view model is a single object which contain a list property you need to itterate the property not the whole model

Create an ASP.NET MVC Html helper similar to DropDownListFor

In certain cases I want to display SelectList object not using DropDownListFor helper. Instead, I want to create a helper that iterates over the SelectListItems, and draw something different.
I have created an EditorTemplate:
#model RadioButtonOptions
<div class=" switch-field noselect" style="padding-left: 0px;">
#foreach (SelectListItem op in Model.Values.Items)
{
var idLabelF = ViewData.TemplateInfo.GetFullHtmlFieldId("") + "_" + op.Value;
var esChecked = "";
if (op.Selected)
{
esChecked = "checked";
}
<input type="radio" id="#idLabelF" name="#(ViewData.TemplateInfo.GetFullHtmlFieldName(""))" value="#op.Value" #esChecked />
<label for="#idLabelF" style="width: 100px;">#op.Text</label>
}
</div>
The RadioButtonOptions class is a ViewModel:
public class RadioButtonOptions
{
public SelectList Values { get; set; }
}
The final resul looks like this:
My ViewModel is like this (simplified):
public class MainVisitVM
{
public MainVisit Visit { get; set; }
public RadioButtonOptions VisitOptions { get; set; }
}
And I use it in Razor View as:
<div class="clearfix">
#Html.LabelFor(x=> x.Visit.Tipo)
<div class="input">
#Html.EditorFor(x=> x.VisitOptions ) //HERE
</div>
</div>
The problem I have is that I want this to work more like the DropDownListFor, so the lamda expresion I pass is the property holding the selected value, and then just pass the SelectList object (or a custom list).
<div class="clearfix">
#Html.LabelFor(x=> x.Visit.Tipo)
<div class="input">
#Html.CustomDropDownListFor(x=> x.Visit.Tipo, Model.VisitOptions ) //This would be ideal!!
</div>
</div>
So, I think doing this using EditorTemplates will not be possible.
Any idea in how to accomplish this?
Thanks to #StephenMuecke suggestion, I ended up with this HtmlHelper extension method:
public static MvcHtmlString RadioButtonForSelectList<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
SelectList listOfValues)
{
string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
if (listOfValues == null) return MvcHtmlString.Create(string.Empty);
var wrapperDiv = new TagBuilder("div");
wrapperDiv.AddCssClass("switch-field noselect");
wrapperDiv.Attributes.Add("style", "padding-left: 0px;");
var sb = new StringBuilder();
foreach (SelectListItem item in listOfValues)
{
var idLabelF = htmlFieldName.Replace(".","_") + "_" + item.Value;
var label = htmlHelper.Label(idLabelF, item.Text, new { style = "width: 100px;" }).ToHtmlString();
var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = idLabelF }).ToHtmlString();
sb.AppendFormat("{0}{1}", radio, label);
}
wrapperDiv.InnerHtml = sb.ToString();
return MvcHtmlString.Create(wrapperDiv.ToString());
}
Not particulary proud of my htmlFieldName.Replace(".","_"), but works.

Model returning null value

This is my code for my model
public class ManufacturerModel
{
public int ProductTYpeId { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public List<SelectListItem> manf { get; set; }
public Manufacturer manufacturer { get; set; }
}
This is my code in cshtml file
#using (Html.BeginForm("addmanufacturer", "Admin", FormMethod.Post, new { id = "formPageID" }))
{
<div class="row">
<label>Select Existing Manufacturer<span style="color: Red">*</span>:</label>
<div class="formRight">
#Html.DropDownList("Id", Model.manf)
</div>
</div>
<div class="row">
<label>Manufacturer Name<span style="color: Red">*</span>:</label>
<div class="formRight">
#Html.TextBoxFor(m => m.manufacturer.name)
#Html.ValidationMessageFor(m => m.manufacturer.name)
</div>
</div>
}
I am posting this form and when I am trying to fetch the value from the manfacurer ie - ManufacturerModel manufacturer = new ManufacturerModel();
using a model object all the value are coming out null.
in the text box If I replace it with m => m.Name then I am able to get proper value of Name.
can any one suggest what the problem is
I am using the manf to bind a dropdown. If In case I post back the form and the if it is return the value becomes blank, I need to refill the value..
public ActionResult addmanufacturer(string id)
{
if (id == null)
id = "0";
ManufacturerModel manufacturer = new ManufacturerModel();
manufacturer.ProductTYpeId = Convert.ToInt32(id);
manufacturer.manf = GetManf();
manufacturer.Id = -1;
return View(manufacturer);
}
I think problem will be becouse of:
#using (Html.BeginForm("Action", "Controller", FormMethod, HTML ATTRIBUTES )) { }
You probably want this overload:
#using (Html.BeginForm("Action", "Controller", Route Values, FormMethod, html attributes )) { }
Important is say him that you want route values and not a html atrributes, so try this
#using (Html.BeginForm("addmanufacturer", "Admin", new { id = "formPageID" }, FormMethod.Post, null )) { }
Hope, it helps.
M.

Form with dynamic number of texboxes in ASP.NET MVC

Consider the following model and controller:
public class SimpleModel
{
[Required(ErrorMessage="Email Address is required.")]
[DataType(DataType.EmailAddress)]
[DisplayName("EmailAddress")]
public string EmailAddress { get; set; }
}
[HandleError]
public class SimpleController : Controller
{
public ActionResult Simple()
{
return View();
}
[HttpPost]
public ActionResult Simple(SimpleModel model)
{
if (ModelState.IsValid)
{
// handling code here
}
return View(model);
}
}
... and the relevant section in the matching view:
<% using (Html.BeginForm()) { %>
<%= Html.ValidationSummary(true, "The form submitted is not valid.") %>
<div>
<fieldset>
<div class="editor-label">
<%= Html.LabelFor(m => m.EmailAddress)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(m => m.EmailAddress)%>
<%= Html.ValidationMessageFor(m => m.EmailAddress)%>
</div>
<div class="editor-field">
<input type="submit" value="Submit" />
</div>
</fieldset>
</div>
<% } %>
What would be the best way to modify the model, view and controller to support a dynamic number of email addresses defined by the controller.
Based on an article by Steve Sanderson I was able to find the elegant solution I was looking for:
First of all, the model needs to be modified as follows:
public class SimpleModel
{
public IEnumerable<EmailAddress> EmailAddresses { get; set; }
}
public class EmailAddress
{
[Required(ErrorMessage = "Email Address is required.")]
[DataType(DataType.EmailAddress)]
[DisplayName("Email Address")]
public string Value { get; set; }
}
The controller method handling the GET method needs to prepopulate the model with as many entries as required:
[HandleError]
public class SimpleController : Controller
{
public ActionResult Simple()
{
SimpleModel model = new SimpleModel
{
EmailAddresses =
new List<EmailAddress>
{
// as many as required
new EmailAddress { Value = string.Empty },
new EmailAddress { Value = string.Empty },
new EmailAddress { Value = string.Empty }
}
};
return View(model);
}
[HttpPost]
public ActionResult Simple(SimpleModel model)
{
if (ModelState.IsValid)
{
// handling code here
}
return View(model);
}
}
The view also needs to change:
<% using (Html.BeginForm()) { %>
<%= Html.ValidationSummary(true, "The form submitted is not valid.") %>
<div>
<fieldset>
<% foreach (var item in Model.EmailAddresses)
Html.RenderPartial("SimpleRows", item);
%>
<div class="editor-field">
<input type="submit" value="Submit" />
</div>
</fieldset>
</div>
<% } %>
... and a new partial view needs to be created. Note that the view is strongly-type with the type of the collection item.
<% using(Html.BeginCollectionItem("EmailAddresses")) { %>
<div class="editor-label">
<%= Html.LabelFor(x => x.Value)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(x => x.Value)%>
<%= Html.ValidationMessageFor(x => x.Value)%>
</div>
<% }%>
The BeginCollectionItem is a Helper method created by Sanderson:
public static class HtmlPrefixScopeExtensions
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
{
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex)));
return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,
// otherwise the framework won't render the validation error messages next to each item.
string key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null) {
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
}
... and that's it... when you post the form the model will be automatically populated and passed to the controller action handling the POST method.
Note that with this solution all the attributes including the validation work as expected.
public class SimpleModel
{
[Required(ErrorMessage = "Email Address is required.")]
[DataType(DataType.EmailAddress)]
[DisplayName("EmailAddress")]
public List<string> EmailAddress { get; set; }
}
[HandleError]
public class SimpleController : Controller
{
public ActionResult SimpleTest()
{
SimpleModel model = new SimpleModel();
model.EmailAddress = new List<string>();
model.EmailAddress.Add("email1");
model.EmailAddress.Add("email2");
return View(model);
}
[HttpPost]
public ActionResult SimpleTest(FormCollection formvalues)
{
if (ModelState.IsValid)
{
// handling code here
}
SimpleModel model = new SimpleModel();
model.EmailAddress = new List<string>();
model.EmailAddress.Add("email1");
model.EmailAddress.Add("email2");
return View();
}
}
... and the relevant section in the matching view:
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true)%>
<fieldset>
<legend>Fields</legend>
<%{
foreach (var i in Model.EmailAddress)
{ %>
<div class="editor-label">
<%: Html.LabelFor(model => model.EmailAddress)%>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model =>i)%>
<br />
</div>
<%}
}%>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
I don't think the validation will work though.
I also marked the answer by #JCallico as correct.
For any die-hard VB coders here's the extension method by Steve Sanderson in your favourite language:
'from http://stackoverflow.com/questions/5236251/form-with-dynamic-number-of-texboxes-in-asp-net-mvc based on http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
Imports System.IO
Imports System.Web.Mvc
Imports System.Web
Imports System.Collections.Generic
Namespace HtmlHelpers.BeginCollectionItem
Public Module HtmlPrefixScopeExtensions
Private Const IdsToReuseKey As String = "__htmlPrefixScopeExtensions_IdsToReuse_"
<System.Runtime.CompilerServices.Extension> _
Public Function BeginCollectionItem(html As HtmlHelper, collectionName As String) As IDisposable
Return BeginCollectionItem(html, collectionName, html.ViewContext.Writer)
End Function
<System.Runtime.CompilerServices.Extension> _
Public Function BeginCollectionItem(html As HtmlHelper, collectionName As String, writer As TextWriter) As IDisposable
Dim idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName)
Dim itemIndex = If(idsToReuse.Count > 0, idsToReuse.Dequeue(), Guid.NewGuid().ToString())
' autocomplete="off" is needed to work around a very annoying Chrome behaviour
' whereby it reuses old values after the user clicks "Back", which causes the
' xyz.index and xyz[...] values to get out of sync.
writer.WriteLine("<input type=""hidden"" name=""{0}.index"" autocomplete=""off"" value=""{1}"" />", collectionName, html.Encode(itemIndex))
Return BeginHtmlFieldPrefixScope(html, String.Format("{0}[{1}]", collectionName, itemIndex))
End Function
<System.Runtime.CompilerServices.Extension> _
Public Function BeginHtmlFieldPrefixScope(html As HtmlHelper, htmlFieldPrefix As String) As IDisposable
Return New HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix)
End Function
Private Function GetIdsToReuse(httpContext As HttpContextBase, collectionName As String) As Queue(Of String)
' We need to use the same sequence of IDs following a server-side validation failure,
' otherwise the framework won't render the validation error messages next to each item.
Dim key = IdsToReuseKey & collectionName
Dim queue = DirectCast(httpContext.Items(key), Queue(Of String))
If queue Is Nothing Then
httpContext.Items(key) = InlineAssignHelper(queue, New Queue(Of String)())
Dim previouslyUsedIds = httpContext.Request(collectionName & Convert.ToString(".index"))
If Not String.IsNullOrEmpty(previouslyUsedIds) Then
For Each previouslyUsedId In previouslyUsedIds.Split(","c)
queue.Enqueue(previouslyUsedId)
Next
End If
End If
Return queue
End Function
Friend Class HtmlFieldPrefixScope
Implements IDisposable
Friend ReadOnly TemplateInfo As TemplateInfo
Friend ReadOnly PreviousHtmlFieldPrefix As String
Public Sub New(templateInfo__1 As TemplateInfo, htmlFieldPrefix As String)
TemplateInfo = templateInfo__1
PreviousHtmlFieldPrefix = TemplateInfo.HtmlFieldPrefix
TemplateInfo.HtmlFieldPrefix = htmlFieldPrefix
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
TemplateInfo.HtmlFieldPrefix = PreviousHtmlFieldPrefix
End Sub
End Class
Private Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
target = value
Return value
End Function
End Module
End Namespace
I am happily using this with Value Injector.

Resources