MVC Razor Html helper - asp.net-mvc

In Asp.net MVC 4, I want to make a html extend method.
I want it work like this:
in Razor View:
<button type='button' click='domethod'>click</button>
#helper.minify(
<script>
function domethod() {
alert('I'm script!');
}
</script>
);
I think how can I make it render:
<button type='button' click='domethod'>click</button>
<script>function domethod() {alert('I'm script!');}</script>
May I create a extend in backcode, that it can recevie <script Tag> ?

you can use Extensions:
public static class Extensions
{
public static MvcHtmlString Test(this HtmlHelper html, string expression)
{
return new MvcHtmlString("Data");
}
}
#Html.Test("my test")

Related

passing html attributes to Html.Actionlink helper function

i want to know that how to pass html attributes to #Html.ActionLink helper function
i want to do like that
<a class="accordion-toggle" data-toggle="collapse" data-parent="#leftMenu" href="/Admin/UserManagment">
<i class="icon-user"></i>User Managment
</a>
how to pass that italic html attribute
You could use #Url.Action() as an alternative.
In this case your code would look like this:
<a class="accordion-toggle" data-toggle="collapse" data-parent="#leftMenu"
href="#Url.Action("UserManagment", "Admin")">
<i class="icon-user"></i>User Managment
</a>
Edit:
Out of interest I did a bit of research and found this answer. Which explains it isn't possible to use the Html.ActionLink for this purpose:
The Html.ActionLink helper HTML encodes the link text which prevents
you from embedding HTML in the link text.
There is no way to wrap html code inside the anchor tag using #Html.ActionLink
You can use #Url.Action
<a href="#Url.Action("UserManagment", "Admin")" ...>
<i class="icon-user"></i>User Managment
</a>
Or create an extension method:
public static IHtmlString MyActionLink(this HtmlHelper helper,
string value,
Dictionary<string, string> attributes,
string innerHtml)
{
var aBuilder = new TagBuilder("a");
foreach (var attr in attributes)
{
aBuilder.MergeAttribute(attr.Key, attr.Value);
}
aBuilder.InnerHtml += innerHtml + value;
return new HtmlString(aBuilder.ToString(TagRenderMode.Normal));
}
And use it in your views like this
#{
var attributes = new Dictionary<string, string>
{
{ "data-toggle", "collapse" },
{ "data-parent", "#leftMenu" },
{ "href", Url.Action("UserManagement", "Admin") }
};
var innerHtml = "<i class='icon-user'></i>";
}
#Html.MyActionLink("User Managment", attributes, innerHtml)

How do you get BeginForm to use a standard accept-charset by default?

I have a website I manage that has a lot of content. Since we do have to deal with international characters, I want all my forms to have the accept-charset="utf-8" attribute. Right now I have to remember, and have my team remember to set that explicitly on every form in our website:
#using (Html.BeginForm(null, null, FormMethod.Post, new { accept_charset = "utf-8" })) {
<!-- content of form -->
}
I want to be able to configure the whole site to put that in by default. In short I want this code:
#using (Html.BeginForm()) {
<!-- content of form -->
}
to generate this HTML:
<form action="/Teaching/Edit/2522" method="post" accept-charset="utf-8">
<!-- content of form -->
</form>
I haven't been able to find anything to let me do that.
You can create a helper class that contains static mvcHtmlString methods. Within this, create a 'beginDefaultForm' method to return a BeginForm statement containing your default options:
FormHelper:
public static class FormHelper
{
public static MvcForm BeginDefaultForm(this HtmlHelper helper)
{
return helper.BeginForm("actionName", "controllerName",
FormMethod.Post, new { accept_charset = "utf-8" });
}
}
View:
// reference the form helper namespace
#using FormHelperNamespace
// call beginDefaultForm
#Html.BeginDefaultForm()
You may need to play around with the actionName / controllerName to get the desired route.
Hope this helps.

Looking for alternate ways to create blocks of HTML code in ASP.NET MVC 3

I'm not sure how to phrase my question, so I essentially want to be able to do something like this, in ASP.NET MVC 3:
#myJsHtmlCustomCode
{
<div><h1>Title</h1></div>
}
where anything in that myJsHtmlCustomCode block would be surrounded with some custom JavaScript/HTML code that I wrote.
I know I could use something like myJsHtmlCustomCode.Begin() and myJsHtmlCustomCode.End() in my code, but that doesn't provide the same formatting structure.
If anyone knows of a similar way to achieve the same objective, and get the automatic outlining/indent formatting, that would be great.
Just for reference, I wanted the the #myJsHtmlCustomCode to surround the code with for instance, another <div id="myTestId" onclick="thisClickEvent"></div> for the resulting code to look like...
<div id="myTestId" onclick="thisClickEvent">
<div><h1>Title</h1></div>
</div>
Option 1
You can wrap your code in an object that implements IDisposable, just like you use #using (Html.BeginForm())
Your code could be like this:
public class MyJsHtmlCustomCode : IDisposable {
private ViewContext _ctx;
public MyJsHtmlCustomCode (HtmlHelper html, /* other params */) {
_ctx = html.ViewContext;
/* Write begin tags */
_ctx.Writer.Write("html => opening tags"); }
public Dispose() {
_ctx.Writer.Write("html => closing tags");
}
}
and the extension:
public static MyJsHtmlCustomCode BeginMyJsHtmlCustomCode(this HtmlHelper html /* other params */) {
var result = new MyJsHtmlCustomCode(html);
return result;
}
Usage:
#using(Html.BeginMyMyJsHtmlCustomCode()) {
<div>This is surrounded by your code </div>
}
Option 2
You can use Razor Templated Delegates:
#{
Func<dynamic, object> b = #<strong>#item</strong>;
}
<span>This sentence is #b("In Bold").</span>
<div>#b(
#<span>
#DateTime.Now
</span><span>Example of more complex logic
</span>
)</div>
While I must admit I do not completely understand your question, whenever I need to do programatic custom HTML manipulation in .Net MVC 3 I use the Html Agility Pack.
Could you achieve your desired result using #section ?
e.g.: in one cshtml, possibly the _Layout:
<script type="text/javascript">
// whatever you want
// more whatever you want
#RenderSection("jsCode", false)
// even more whatever you want
</script>
Then in your actual view cshtml:
#section jsCode{
<div><h1>Title</h1></div>
}
You could possibly use a partial view for the js bit e.g.

Creating Some thing #using (Html.BeginForm()) Helpers

In Asp.net MVC3 when you write below code , it generates wrapping html itself
#using (Html.BeginForm()) {
#Html.ValidationMessageFor(model => model.Text)
}
It generates codes in below format,
<form method="post" action="/Feeds">
<!-- Fields Here -->
</form>
My question in #using (Html.BeginForm()) automatically adds <form> tag at beginning and end, how can i create something like that of my own.
I am looking for some thing like below
#using (Html.BeginMYCUSTOMDIV())
{
I am text inside div
}
Expected Generated Output
<div class="customDivClass">
I am text inside div
</div>
Something along the lines:
public class MyDiv : IDisposable
{
private readonly TextWriter _writer;
public MyDiv(TextWriter writer)
{
_writer = writer;
}
public void Dispose()
{
_writer.WriteLine("</div>");
}
}
public static class MyExtensions
{
public static MyDiv BeginMYCUSTOMDIV(this HtmlHelper htmlHelper)
{
var div = new TagBuilder("div");
div.AddCssClass("customDivClass");
htmlHelper.ViewContext.Writer.WriteLine(div.ToString(TagRenderMode.StartTag));
return new MyDiv(htmlHelper.ViewContext.Writer);
}
}
and in the view:
#using (Html.BeginMYCUSTOMDIV())
{
<span>Hello</span>
}
generates:
<div class="customDivClass">
<span>Hello</span>
</div>
If I'm not mistaken, Html.BeginForm() returns an IDisposable object. When used in the using block, the object's Disposemethod is called, which is the responsible to write the closing tag to the output.
how does using HtmlHelper.BeginForm() work?
Html.BeginForm() type of extension

Is it possible to create a generic #helper method with Razor?

I am trying to write a helper in Razor that looks like the following:
#helper DoSomething<T, U>(Expression<Func<T, U>> expr) where T : class
Unfortunately, the parser thinks that <T is the beginning of an HTML element and I end up with a syntax error. Is it possible to create a helper with Razor that is a generic method? If so, what is the syntax?
This is possible to achieve inside a helper file with the #functions syntax but if you want the razor-style readability you are referring to you will also need to call a regular helper to do the HTML fit and finish.
Note that functions in a Helper file are static so you would still need to pass in the HtmlHelper instance from the page if you were intending to use its methods.
e.g.
Views\MyView.cshtml:
#MyHelper.DoSomething(Html, m=>m.Property1)
#MyHelper.DoSomething(Html, m=>m.Property2)
#MyHelper.DoSomething(Html, m=>m.Property3)
App_Code\MyHelper.cshtml:
#using System.Web.Mvc;
#using System.Web.Mvc.Html;
#using System.Linq.Expressions;
#functions
{
public static HelperResult DoSomething<TModel, TItem>(HtmlHelper<TModel> html, Expression<Func<TModel, TItem>> expr)
{
return TheThingToDo(html.LabelFor(expr), html.EditorFor(expr), html.ValidationMessageFor(expr));
}
}
#helper TheThingToDo(MvcHtmlString label, MvcHtmlString textbox, MvcHtmlString validationMessage)
{
<p>
#label
<br />
#textbox
#validationMessage
</p>
}
...
No, this is not currently possible. You could write a normal HTML helper instead.
public static MvcHtmlString DoSomething<T, U>(
this HtmlHelper htmlHelper,
Expression<Func<T, U>> expr
) where T : class
{
...
}
and then:
#(Html.DoSomething<SomeModel, string>(x => x.SomeProperty))
or if you are targeting the model as first generic argument:
public static MvcHtmlString DoSomething<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expr
) where TModel : class
{
...
}
which will allow you to invoke it like this (assuming of course that your view is strongly typed, but that's a safe assumption because all views should be strongly typed anyways :-)):
#Html.DoSomething(x => x.SomeProperty)
In all cases the TModel will be the same (the model declared for the view), and in my case, the TValue was going to be the same, so I was able to declare the Expression argument type:
#helper FormRow(Expression<Func<MyViewModel, MyClass>> expression) {
<div class="form-group">
#(Html.LabelFor(expression, new { #class = "control-label col-sm-6 text-right" }))
<div class="col-sm-6">
#Html.EnumDropDownListFor(expression, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(expression)
</div>
}
If your model fields are all string, then you can replace MyClass with string.
It might not be bad to define two or three helpers with the TValue defined, but if you have any more that would generate some ugly code, I didn't really find a good solution. I tried wrapping the #helper from a function I put inside the #functions {} block, but I never got it to work down that path.
if your main problem is to get name attribute value for binding using lambda expression seems like the #Html.TextBoxFor(x => x.MyPoperty), and if your component having very complex html tags and should be implemented on razor helper, then why don't just create an extension method of HtmlHelper<TModel> to resolve the binding name:
namespace System.Web.Mvc
{
public static class MyHelpers
{
public static string GetNameForBinding<TModel, TProperty>
(this HtmlHelper<TModel> model,
Expression<Func<TModel, TProperty>> property)
{
return ExpressionHelper.GetExpressionText(property);
}
}
}
your razor helper should be like usual:
#helper MyComponent(string name)
{
<input name="#name" type="text"/>
}
then here you can use it
#TheHelper.MyComponent(Html.GetNameForBinding(x => x.MyProperty))

Resources