Helper for tag html a - asp.net

is there any helper in asp.net MVC3
Go to Google
?
Not for an action but to a static link

I don't believe there is, but I'm not sure why you would want one. You'd actually end up with more code:
Go to Google
<%: Html.Link("http://www.google.com/", "Go to Google") %>
#Html.Link("http://www.google.com/", "Go to Google")
Update: If you want to create a Link() helper like that above, you would use an extension method:
public static class LinkExtensions
{
public static MvcHtmlString Link(this HtmlHelper helper, string href, string text)
{
var builder = new TagBuilder("a");
builder.MergeAttribute("href", href);
builder.SetInnerText(text);
return MvcHtmlString.Create(builder.ToString(TagRenderMode.Normal));
}
}

Related

Asp.NET MvcHtmlString and ModelMetadata.FromLambdaExpression to AspNetCore?

How to convert this code to AspNetCore
public static MvcHtmlString ChqLabelFor<TModel, TValue>(this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression, object htmlAttributes)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
string resolvedLabelText = metadata.DisplayName ?? metadata.PropertyName;
if (metadata.IsRequired)
{
resolvedLabelText += "*";
}
return LabelExtensions.LabelFor<TModel, TValue>(html, expression, resolvedLabelText, htmlAttributes);
}
I know that I can use now instead of MvcHtmlString just HtmlString
What to do with
ModelMetadata.FromLambdaExpression
I couldn't find any alternative ...
Those helpers still exist, but they are buried a little.
var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, htmlHelper.ViewData, htmlHelper.MetadataProvider);
You can then access the metadata with
modelExplorer.Metadata
and the model itself with
modelExplorer.Model
I've got some example code here that uses it for PowerBI Embedded report rendering.
https://blogs.endjin.com/2016/09/how-to-use-power-bi-embedded-with-aspnetcore/
From the #willDaBeast comment on the other answer, what worked for me was the following code that I provided as a separate answer for better formatting. Although it might not be the recommended practice.
ModelExpressionProvider expressionProvider = new ModelExpressionProvider(htmlHelper.MetadataProvider);
var metadata = expressionProvider.CreateModelExpression(htmlHelper.ViewData,expression);
In netcore 3.0:
Get an instance of ModelExpressionProvider from DI
Use CreateModelExpression method
var metadata = _modelExpressionProvider.CreateModelExpression(ViewData, expression).Metadata;
P.S
In order to extend HtmlHelper, I would suggest another approach:
public class CustomHtmlHelper : HtmlHelper, ICustomHtmlHelper
{
// add your extension methods here and in ICustomHtmlHelper
// _modelExpressionProvider will be part of constructor
// register implementation in DI
}
and use the new helper in views:
#inject ICustomHtmlHelper Html

ASP.net partial view relative action links

Is there a way to have action links which are relative to the current view.
For example, lets say I have a partial view which is a contains a paged list of news articles called _ArticlesList. I want to include this in the Admin and Index views, which are controlled by their relative controllers. _ArticlesList produces URLs which have the routeValues pageNumber and pageSize, but you have to hard code the controller, don't you?
I think what I want to do is just override properties in the routeValue object?
Edit:
I guess I could use HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString()
but that looks pretty bad
If you want to upload in For EX. Index file then write following to implement in your cshtml.
<div>
#Html.Partial("_ArticleList", Model)
</div>
You can put this in any div tag.
I used this to achieve what I wanted
public static class UrlHelperExtensions
{
public static string RelativeAction(this UrlHelper url, object routeValues)
{
var routeDataValues = url.RequestContext.RouteData.Values;
var queryString = url.RequestContext.HttpContext.Request.QueryString;
foreach (string key in queryString.Keys)
{
routeDataValues[key] = queryString[key];
}
// Allow routeValue object to take precedence over queryString
foreach (var prop in new RouteValueDictionary(routeValues))
{
routeDataValues[prop.Key] = prop.Value;
}
return url.RouteUrl(routeDataValues);
}
}

Unit Testing An Extension Method on HtmlHelper

I have an HTMLHelper extension method that outputs HTML to Response.Write. How best to unit test this?
I'm considering mocking the HtmlHelper passed into the method, but am unsure as to how I should verify the HTML sent to Response.Write.
Thanks
If you are using an HTML helper to output text to the browser why not have it return a string and in your view do something like ...
<%=Html.YourExtension() %>
It makes it a great deal more testable.
Kindness,
Dan
EDIT:
Modification would be a change of signature
public static void YourExtension(this HtmlHelper html)
{
...
Response.Write(outputSting);
}
to
public static string YourExtension(this HtmlHelper html)
{
...
return outputSting;
}
I use the following code to test and validate html helpers. If you are doing anything complex, like disposable based helpers like beginform or helpers with dependencies you need a better test framework then just looking at the string of a single helper.
Validation is a another example.
Try the following:
var sb = new StringBuilder();
var context = new ViewContext();
context.ViewData = new ViewDataDictionary(_testModel);
context.Writer = new StringWriter(sb);
var page = new ViewPage<TestModel>();
var helper = new HtmlHelper<TestModel>(context, page);
//Do your stuff here to exercise your helper
//Get the results of all helpers
var result = sb.ToString();
//Asserts and string tests here for emitted HTML
Assert.IsNotNullOrEmpty(result);
This works if the method "YourExtension" is simply using HtmlHelper methods that return string or HtmlString. But methods like "BeginForm" return MvcForm object and also the form tag is written directly on TextWriter that HtmlHelper has reference to.

ASP.Net MVC - Generate an ActionLink from code behind?

I have a number of permissions, and based on a set of conditions these permission determine if a user can see certain features. I have written a helper function for this as the logic in the view became quite extensive.
Essentially I'm looking for a function the same as Html.ActionLink that I can access from a class file (Ideally if I can access the Helper that would be great) So I can do somthing like so,
public static string GetAdminLinks()
{
if(PermCheck)
{
return(Html.ActionLink(...));
}
}
Any sugestions?
in controller:
Url.Action("Index", "Home", null, Request.Url.Scheme);
It largely depends on how your permission check is implemented (and of which information it needs to determine the user's permissions). Anyhow, I'd implement it as an extension to the HtmlHelper class.
Somewhere in your App_Code:
using System.Web.Mvc.Html;
public static class HtmlHelperExtensions {
public static string SecureActionLink(this HtmlHelper htmlHelper, string action, string controller){
if(PermCheck)
return htmlHelper.ActionLink(action, controller);
else
return string.Empty;
}
//add other ActionLink overrides if you like...
}
Then you'll be able to call the extension method from anywhere in your ViewPages without any code behind.

How do you get access to the current System.Web.Routing.RequestContext from within a custom helper method in ASP.NET MVC?

I'm writing a helper method for ASP.NET MVC and I need to call Url.Content to get an appropriate URL for the context. However, in order to create a new UrlHelper() I need to get the current RequestContext (System.Web.Routing.RequestContext to be precise) and I'm not sure how to grab it. Anyone know?
If the current IHttpHandler is MvcHandler, you can use
((MvcHandler)HttpContext.Current.Handler).RequestContext
Noticed this was still unanswered. As of MVC 1.0 you can do:
public static string NewHelperMethod(this HtmlHelper helper)
{
UrlHelper url = new UrlHelper(helper.ViewContext.RequestContext);
You may have found an answer elsewhere, but here goes;
In a controller action, you can get to the current RequestContext like so:
public ActionResult SomeAction(){
var helper = new UrlHelper(this.ControllerContext.RequestContext);
...
}
As mentioned above, just extend the HtmlHelper and the context is exposed in that way. For example:
public static string ExtensionMethodName(this HtmlHelper html,object o)
{
html.ViewContext.HttpContext.Request.Uri ... etc
}
Don't create a new one. Just extend the existing UrlHelper, just like you'd extend HtmlHelper:
public static string IdLink(this UrlHelper helper, Guid id)
{ //...
If you must use both HtmlHelper and UrlHelper, pass one of them as a regular (non-"this") argument.

Resources