0

my scenario:

I am finally getting around to creating my own blog, and I am trying to learn as much as possible with regards to MVC while doing so. I am trying to display my tags as a custom declarative helper in my "PostView.cshtml" file but my problem is that it isn't in the current context and I don't know how to make it so.

I have had a look at the following 2 questions on SO:

this one is for previous version of MVC (<= 4) and

this one was answered by the guy who asked the question and isn't very explanatory.

I tried the above advice but with no success, hopefully someone can help me out. Here is my code:

Tags.cshtml (in ~/Views/Helpers/):

@helper Tags(System.Web.Mvc.HtmlHelper htmlHelper,
ICollection<MyNamespace.Objects.Tag> tags)
{
    foreach (var tag in tags)
    {
        <div class="tags-div">
            @MyNamespace.Extensions.ActionLinkExtensions.TagLink(htmlHelper, tag):
        </div>
    }
}

ActionLinkExtensions.cs (in ~/Extensions/ActionLinkExtensions/)

namespace MyNamespace.Extensions
{
    public static class ActionLinkExtensions
    {
        public static MvcHtmlString TagLink(this HtmlHelper helper, Tag tag)
        {
            return helper.ActionLink("", ""); //logic removed for simplicity
        }
    }
}

PostView.cshtml (in ~/Views/Shared/) //where i want to use my custom helper:

@model MyNamespace.Objects.Post
<!--extra html removed for simplicity-->
<div>
    <span>Tags:</span>@Tags(Html, Model.Tags) // '@Tags' doesn't exist in current context
</div>

I also tried adding namespaces to '~/Views/web.config':

<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Optimization"/>
    <add namespace="System.Web.Routing" />
    <add namespace="MyNamespace" />
    <add namespace="MyNamespace.Extensions" />
  </namespaces>
</pages>

My "full name" for my "Tag.cs" class is MyNamespace.Objects.Tag and "Post".cs" is MyNamespace.Objects.Post.

Any explanations and advice with an answer would be greatly appreciated too, thank you very much in advance.

Community
  • 1
  • 1
EaziLuizi
  • 1,557
  • 1
  • 16
  • 25

2 Answers2

2

I decided to try use MVC3 way, I added the App_Code folder manually and followed steps from this great article. And it worked, I needed to restart Visual Studio for my Intellisense to work (which prolonged finding my solution).

I deleted the folder '~/Views/Shared/'

I Added a file MyHelpers.cshtml into the App_Code folder, inside the file I added my helper method:

@helper Tags(System.Web.Mvc.HtmlHelper htmlHelper,
    ICollection<MyNamespace.Objects.Tag> tags)
{
    foreach (var tag in tags)
    {
        <div class="tags-div">
            @MyNamespace.Extensions.ActionLinkExtensions.TagLink(htmlHelper, tag)
        </div>
    }
}

And called it in my PostView.cshtml like so:

@MyHelpers.Tags(Html, Model.Tags)

And Viola works as expected... hopefully this helps someone else who ends up in this situation...

EaziLuizi
  • 1,557
  • 1
  • 16
  • 25
0

I believe the better and simpler way would be to define a display template for you Tags collection that would be placed in ~Views/Shared/DisplayTemplates:

@model ICollection<MyNamespace.Objects.Tag>

foreach (var tag in Model)
{
    <div class="tags-div">
        @MyNamespace.Extensions.ActionLinkExtensions.TagLink(htmlHelper, tag)
    </div>
}

In your PostView.cshtml you would then just write:

@Html.DisplayFor(model => model.Tags)
maxshuty
  • 9,708
  • 13
  • 64
  • 77
Vilius K.
  • 68
  • 3
  • 8