3
<div id="header-content"> <a href="@Url.Action("Index", "Home")"> <img class="mainlogo" src="@Url.Content("~/Public/images/logo.png")"/> </a> @{ using (EFJugadorRepository repository = new EFJugadorRepository()) { var playersOnline = repository.FindAllJugadores().Where(j => j.jugEstado == 100).Count(); } using (EFEstadisticaMesaRepository estadisticaMesaRepository = new EFEstadisticaMesaRepository()) { var tablesInPlay = estadisticaMesaRepository.GetTablesInPlayCount; var availableTables = estadisticaMesaRepository.GetAvailableTablesCount; } } <div id="players"> <p>Jogadores Online: <span class="onlinecount">@playersOnline</span></p> <p>Mesas Jogando: <span class="onlinecount">213</span></p> <p>Mesas Disponiveis: <span class="onlinecount">850</span></p> </div> <div id="login"> @Html.Partial("_LogOnPartial") </div> </div> 

I'm trying to use the @playersOnline variable in my Razor code, but it says it is not declared.

Cannot resolve symbol 'playersOnline'.

Any idea why I can't access that variable?

Is it because it's declared within a using statement?

4
  • 3
    Any particular reason for writing this code of code in your veiws? By kind of code I mean code that usually belongs to a data access layer rather than a view. Or more precisely in your case the kind of code that is trying to accomplish something that view models are supposed to accomplish in ASP.NET MVC. I really cannot believe what people end up doing just because they don't use view models. That's horrible. Looks like PHP (when done wrong) or classic ASP. I would really recommend you take a moment and read about view models before going any further with ASP.NET MVC. Commented Nov 7, 2011 at 15:45
  • @DarinDimitrov: This is within the _layout.cshtml file. How would you access this information without repeating yourself? Commented Nov 7, 2011 at 15:50
  • 2
    very easily: as always in ASP.NET MVC you start by writing a view model that will represent this data. Then you write a controller action that will query your DAL and obtain domain models. Then it will map those domain models back to a view model. Then it will pass this view model to a corresponding partial view. Now all that's left in your Layout is to invoke this child action, like this @Html.Action("FooAction", "Bar"). So you basically replace what you have shown in your view by a single call to the Html.Action helper. Would you like me posting an example or you will figure it out? Commented Nov 7, 2011 at 15:51
  • @DarinDimitrov: An example would be nice of you. :) I'll start reading about Html.Action in the meantime. I do use ViewModels always within regular actions, but since this was in the _layout and I didn't have knowledge of the Html.Action helper, this solution came to mind. Commented Nov 7, 2011 at 15:56

3 Answers 3

4

Yes, it is because it's declared inside the using statment.

Everything declared in the using statement is scoped for that codeblock. The same as an if statement would be.

Just put your variable decleration outside of the using:

int playersOnline = 0; using (EFJugadorRepository repository = new EFJugadorRepository()) { playersOnline = repository.[...]).Count(); } 

As has been pointed out in the comments, your code doesn't seem to belong in the view layer. Have a think about how you're structuring your code and take some tips from Darin.

Sign up to request clarification or add additional context in comments.

Comments

1

Is it because it's declared within a using statement?

Yes. This variable is not visible outside of using scope.

You can do something like this:

<div id="players"> @using (EFJugadorRepository repository = new EFJugadorRepository()) { var playersOnline = repository.FindAllJugadores().Where(j => j.jugEstado == 100).Count(); <p>Jogadores Online: <span class="onlinecount">@playersOnline</span></p> } <p>Mesas Jogando: <span class="onlinecount">213</span></p> <p>Mesas Disponiveis: <span class="onlinecount">850</span></p> </div> 

Comments

1

See my comments on the question for more context so that I don't repeat myself why I am posting this answer.

So we start by declaring a view model:

public class PlayersStatsViewModel { public int PlayersOnline { get; set; } public int TablesInPlay { get; set; } public int AvailableTables { get; set; } } 

then we write a dedicated controller:

public class PlayersController: Controller { [ChildActionOnly] public ActionResult Index() { var model = new PlayersStatsViewModel(); // TODO: You should absolutely use DI here and replace this hardcoding using (var repository = new EFJugadorRepository()) { model.PlayersOnline = repository.FindAllJugadores().Where(j => j.jugEstado == 100).Count(); } // TODO: You should absolutely use DI here and replace this hardcoding using (var estadisticaMesaRepository = new EFEstadisticaMesaRepository()) { model.TablesInPlay = estadisticaMesaRepository.GetTablesInPlayCount; model.AvailableTables = estadisticaMesaRepository.GetAvailableTablesCount; } return PartialView(model); } } 

next you write the corresponding partial view (~/Views/Players/Index.cshtml):

@model PlayersStatsViewModel <div id="players"> <p> Jogadores Online: <span class="onlinecount"> @Html.DisplayFor(x => x.PlayersOnline) </span> </p> <p> Mesas Jogando: <span class="onlinecount"> @Html.DisplayFor(x => x.TablesInPlay) </span> </p> <p> Mesas Disponiveis: <span class="onlinecount"> @Html.DisplayFor(x => x.AvailableTables) </span> </p> </div> 

and the final step is to cleanup your layout:

<div id="header-content"> <a href="@Url.Action("Index", "Home")"> <img class="mainlogo" src="@Url.Content("~/Public/images/logo.png")"/> </a> @Html.Action("Index", "Players") <div id="login"> @Html.Partial("_LogOnPartial") </div> </div> 

Don't ignore the two TODOs I left in the Index controller action. They are important. Right now your controller is tightly coupled to the way you are accessing your data (seems like EF or something). Layers in your application should be as tightly coupled as possible. And to achieve this you should work with abstractions. You should abstract away your data access layer behind interfaces. Then have your controller take those repository interfaces as constructor arguments. Finally you would simply configure your DI framework to serve the correct implementations (for example EF or whatever).

3 Comments

To be honest I've tried using DI for three projects right now and I just don't see the benefits I could gain from it at this time. I understand what it does and why it's useful, but since I'm not using unit tests (no time with my work schedule) and the back end has a 99.999% chance not to change, DI wouldn't do anything for me but complicate things needlessly.
Thanks for this example, but I can't seem to find official documentation from Html.Partial, MSDN turns up empty. Where can I find official docs for MVC3?
@SergioTapia, you mean Html.Action? Phil Haack wrote a nice blog post about it: haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx As far as the official documentation is concerned here you go: msdn.microsoft.com/en-us/library/ee728618.aspx

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.