Не удается получить доступ к переменной, объявленной встроенной в коде Razor - PullRequest
2 голосов
/ 07 ноября 2011
<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>

Я пытаюсь использовать переменную @playersOnline в своем коде Razor, но он говорит, что она не объявлена.

Не удается разрешить символ 'PlayersOnline'.

Есть идеи, почему я не могу получить доступ к этой переменной?

Это потому, что она объявлена ​​в операторе using?

Ответы [ 3 ]

4 голосов
/ 07 ноября 2011

Да, это потому, что оно объявлено внутри using устава.

Все, что объявлено в операторе using, ограничено этим кодовым блоком. Так же, как оператор if будет.

Просто поместите переменную decleration вне использования:

int playersOnline = 0;

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

Как было отмечено в комментариях, ваш код, по-видимому, не принадлежит слою представления. Подумайте, как вы структурируете свой код, и примите несколько советов от Дарина.

1 голос
/ 07 ноября 2011

См. Мои комментарии по этому вопросу для получения дополнительной информации, чтобы я не повторял, почему я публикую этот ответ.

Итак, начнем с объявления модели вида:

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

Затем мы пишем выделенный контроллер:

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);
    }
}

Далее вы пишете соответствующий частичный вид (~/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>

и последний шаг - очистить ваш макет:

<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>

Не игнорируйте два TODO, которые я оставил в действии контроллера индекса. Они важны. Прямо сейчас ваш контроллер тесно связан с тем, как вы получаете доступ к своим данным (похоже на EF или что-то в этом роде). Слои в вашем приложении должны быть максимально тесно связаны. И чтобы добиться этого, вы должны работать с абстракциями. Вы должны абстрагироваться от уровня доступа к данным за интерфейсами. Затем пусть ваш контроллер принимает эти интерфейсы репозитория в качестве аргументов конструктора. Наконец, вы просто сконфигурируете свою инфраструктуру DI для обслуживания правильных реализаций (например, EF или чего-либо еще).

1 голос
/ 07 ноября 2011

Это потому, что оно объявлено в операторе использования?

Да.Эта переменная не отображается за пределами области действия using.

Вы можете сделать что-то вроде этого:

<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>
...