Travis Heeter
Travis Heeter

Reputation: 14074

Trouble calling a custom object in C#

I have an MVC.NET 4 site:

In HomeController.cs I have created a new object (I referred to this article to help me with that), Story, which will hold Strings title and author. Here's that code:

namespace Site.Controllers
{
    public class Story
    {
        public String Title { get; set; }
        public String Author { get; set; }
        public Story(string title, string author)
        {
            Title = title;
            Author = author;
        }
    }

    public class HomeController : Controller
    {
        public Story Story1 = new Story("Test title", "Test author");
        public ActionResult Index()
        {
            return View();
        }
    }
}

This all seems to be working - I'm not getting any errors anyway - but when I try to use it in a cshtml file, I'm getting an error. Here's where the error occurs (in articles.cshtml):

<h1>@Site.Controllers.HomeController.Story.Title</h1>

And the error is

An object reference is required for the non-static field, method, or 
property 'Site.Controllers.HomeController.Story1'

How do I properly use this title I've defined elsewhere?

Another concern is: will I only be able to use the title while on the Home page? I need it to be accessible throughout the site.

Upvotes: 0

Views: 95

Answers (3)

danludwig
danludwig

Reputation: 47375

public class HomeController : Controller
{
    public ActionResult Index()
    {
        Story story1 = new Story("Test title", "Test author");
        return View(story1);
    }
}

...

@model Site.Controllers.HomeController.Story
<h1>@Model.Title</h1>

That said, if you want story1 to be statically accessible from other pages in the site, or even other controller actions on the server, you could construct a static model:

public class HomeController : Controller
{
    public static Story Story1 = new Story("Test title", "Test author");

    public ActionResult Index()
    {
        return View(Story1);
    }

    public ActionResult Action2()
    {
        return View(Story1);
    }

    public ActionResult ActionN()
    {
        return View(Story1);
    }
}

With the above, you could also do something like this:

<h1>@Site.Controllers.HomeController.Story1.Title</h1>

Update

I am not suggesting the use of a static model here. From reading it is clear that the OP does not understand the difference between an object class and an object instance, or at least where that difference lies in C#. The CSHTML error was trying to get to the story title statically, which it could not because the property was not static.

I believe the answer to this question is not so much MVC101, but rather C#101 or even OOP101.

Upvotes: 4

James
James

Reputation: 82096

Your approach is wrong, and in fact, would never work in the way you expect anyway. The main reason being controllers are only available for the lifetime of the request, therefore by the time the view is being rendered the controller would have been disposed.

Also, it's violating one of the fundamentals of using MVC in the first place by coupling your view with your controller. What you should be doing here is passing your model into your view as a parameter i.e.

public ActionResult Index()
{
    return View(new Story("Test title", "Test author"));
}

The model passed to the cshtml file is then accessible from the Model property of the view

@model Site.Controllers.HomeController.Story

<h1>@Model.Title</h1>

This is MVC 101 really.

Upvotes: 0

walther
walther

Reputation: 13600

You have multiple problems in that code...

1.) 2 classes in one file. Class Story shouldn't be in namespace Controllers all, it doesn't make any sense. Please refer to OOP principles and good programming practices.

2.) you try to refer to your value like this <h1>@Site.Controllers.HomeController.Story.Title</h1> but this would mean that there's a static property/variable in HomeController class and you want to get it's property/variable, but that's not the case, is it?

Easiest fix is to pass the value to the view as part of the model

public ActionResult Index()
{
     return View(Story1);
}

Now you can access the value like this:

@model pathToClass.Story
<h1>@Model.Title</h1>

I'd really argue against using static variable in web development, because later you may have a requirement to support different languages etc., and it will become one untestable mess. Always try to use instances whenever possible, especially when dealing with web applications.

3.) work on your naming conventions.. Story1 is really a poor choice.

Upvotes: 0

Related Questions