2009-09-20 2 views
0

Я создаю приложение .NET MVC, у которого есть страница со списком кнопок удаления, по одному для каждого элемента в списке. Проблема, с которой я столкнулась, заключается в том, что переменная «элемент» foreach не видна внутри LoginView, что приводит к следующей ошибке:Почему я не могу использовать переменную итерации в LoginView?

Сообщение об ошибке компилятора: CS0103: имя «элемент» не существует в текущем контексте

Ниже представлена ​​упрощенная версия вида. Ошибка возникает в «новой {ид =} item-id» в LoggedInTemplate - ссылка на «пункт» в ActionLink работает отлично:

<% foreach (var item in Model) { %> 

    <%= Html.ActionLink("Item", "Details", new { id = item.Id })%> 

    <asp:LoginView runat="server"> 
     <LoggedInTemplate> 
      <% using(Html.BeginForm("Delete", "Items", new {id=item.Id}, FormMethod.Post)) 
      { %> 
       <input type="submit" value="Delete" runat="server" /> 
      <% } %> 
     </LoggedInTemplate> 
    </asp:LoginView> 
<% } %> 

Для уточнения проблема не, что модель имеет не был успешно передан в представление. Модель видна как внутри, так и снаружи LoginView. Цикл foreach не представляет проблемы при повторении элементов в модели (которая является списком). Проблема в том, что переменная итерации «item» недоступна из LoginView, хотя исходная модель.

Есть ли способ передать «элемент» через шаблоны LoginView? Или строит LoginViews в пределах foreach, что делает неправильный способ делать что-то?

Есть ли правило определения области, которое предотвращает использование локальных переменных в элементах управления - возможно, потому, что элемент управления отображается в другое время на главной странице?

ответ

1

С ASP.NET MVC вам действительно не следует использовать пользовательские/пользовательские элементы управления, поэтому, если вы опустите <asp:LoginView/> и напишите строку кода, чтобы проверить, проверен ли пользователь, вам хорошо идти.

Вместо текущего кода:

<asp:LoginView runat="server"> 
    <LoggedInTemplate> 
     <div>Show this to authenticated users only</div> 
    </LoggedInTemplate> 
</asp:LoginView> 

просто использовать Условный оператор и значение Request.IsAuthenticated:

<% if (Request.IsAuthenticated) { %> 
    <div>Show this to authenticated users only</div> 
<% } %> 
+0

Я понимаю, что частичные представления обычно являются способом перехода в MVC, но почему правило против пользовательских/пользовательских элементов управления? Это потому, что пользовательские элементы управления делают предположения о Page_Load() и post-back, которые не хранятся в приложении MVC? – ctford

+0

Основная причина этого - область прилагаемой страницы; вы не можете передавать переменные, объявленные в разметке страницы, на любые элементы управления. Это поведение не относится к ASP.NET MVC, но является следствием способа отображения страницы (разметка анализируется и элементы управления отображаются без отношения к любому скрипту, выполняющемуся в разметке). –

+0

Причина, по которой я думаю, что вы должны полностью избегать пользовательских/пользовательских элементов управления, заключается в том, что они обычно не хорошо сочетаются с шаблоном MVC. Они имеют тенденцию смешивать слои и требуют состояния и событий (что не имеет ничего общего с сетью, действительно). Однако во многих случаях это невозможно, но я бы предпочел сделать это надлежащим образом - также избежать таких проблем. –

0

Вы передаете модель в представление и вы также наследуете от модели в этом представлении?

Итак, если это вид, то в коде C# вам нужно вернуть список элементов, таких как return View (listofitems);

Если это частичный вид тогда <% Html.RenderPartial("MyPartial", listofitems) %>

И с точки зрения вам нужно

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IQueryable<ListOfItems>>" %> 

Если все, что находится в месте, то она не должна работать не Probs.

+0

Спасибо, но это не проблема. Модель передается в представление без проблем. Я могу получить доступ к модели как внутри, так и вне LoginView. Это переменная итерации, которая вызывает ошибку компиляции. – ctford

0
<% foreach (var item in Model) { %> 
    <%= Html.ActionLink("Item", "Details", new { id = item.Id })%> 
    <%= if(Request.IsAuthenticated) { 
     using(Html.BeginForm("Delete", "Items", new {id=item.Id}, FormMethod.Post)) 
     { %> 
      <input type="submit" value="Delete" runat="server" /> 
     } 
    } %> 
<% } %> 

Там нет необходимости использовать LoginView, его не действительно давая вам что угодно. Вместо этого используйте что-то вроде выше.

В качестве альтернативы, вы можете переместить решение о том, чтобы показать опцию удаления для конкретного элемента в контроллер, поэтому вместо того, чтобы делать, если (Request.IsAuthenticated) вы могли бы сделать, если (item.ShowDelete) ... Предполагаемый тип элемента - это модель представления. Другой вариант - использовать метод расширения для того же элемента item.ShowDelete(). Я предпочитаю раньше, потому что может быть логика, связанная с решением о том, показывать ли удаление для данного элемента, поэтому лучше не иметь его в контроллере или связанной логике.

Смежные вопросы