В представлении в MVC извлекайте данные из 2 таблиц? [Дубликат]

Мой подход: возьмите идентификатор базы данных, затем Base36 закодируйте его . Я бы не использовал буквы верхнего и нижнего регистров, потому что это делает передачу этих URL по телефону кошмаром, но вы, конечно, можете легко расширить функцию, чтобы быть базовым 62 en / decoder.

262
задан Barrosy 8 June 2016 в 13:13
поделиться

9 ответов

Существует множество способов ...

  1. с вашим файлом BigViewModel:
    @model BigViewModel    
    @using(Html.BeginForm()) {
        @Html.EditorFor(o => o.LoginViewModel.Email)
        ...
    }
    
  2. вы можете создать еще 2 вида Login.cshtml
    @model ViewModel.LoginViewModel
    @using (Html.BeginForm("Login", "Auth", FormMethod.Post))
    {
        @Html.TextBoxFor(model => model.Email)
        @Html.PasswordFor(model => model.Password)
    }
    
    и register.cshtml то же самое после создания вам нужно отобразить их в главном представлении и передать им viewmodel / viewdata, чтобы он выглядел так:
    @{Html.RenderPartial("login", ViewBag.Login);}
    @{Html.RenderPartial("register", ViewBag.Register);}
    
    или
    @{Html.RenderPartial("login", Model.LoginViewModel)}
    @{Html.RenderPartial("register", Model.RegisterViewModel)}
    
  3. с использованием ajax частей вашего сайта становятся более независимыми
  4. iframes, но, вероятно, это не так
242
ответ дан Cosmo Harrigan 19 August 2018 в 00:23
поделиться
  • 1
    Это проблема, если 2 текстовых поля имеют одно и то же имя в форме из-за использования partialviews? – Shawn Mclean 22 January 2011 в 03:44
  • 2
    Нет, следует щелкнуть по самому элементу, используя что-то вроде firebug (на firefox), и вы увидите что-то вроде id = & quot; LoginViewModel_Email & quot; name = & quot; LoginViewModel.Email & quot ;, поэтому на самом деле они уникальны! Модель просмотра должна быть то, что вам нужно, просто разместите каждую страницу на другом URL-адресе, и вы должны быть в порядке – Haroon 22 January 2011 в 10:50
  • 3
    @Lol coder на самом деле это было бы 2 формы, по одному для каждой модели viewmodel, но в любом случае, если бы у вас было бы 2 или 3 или более с таким же именем, вы бы просто получили массив с этим именем на стороне сервера (если вы поместите его в params метода post action) – Omu 22 January 2011 в 11:58
  • 4
    @Chuck Norris Я использую asp.net mvc 4 и реализовал ваш метод partialviewresult, но @Html.RenderAction сообщает об ошибке, которая Expression должна вернуть значение – Deeptechtons 16 October 2012 в 05:10
  • 5
    @ChuckNorris Gotcha, если вы возвращаете View (& quot; BIG_VIEW & quot;) внутри одного из методов actionresult, который принимает значения формы для любой из моделей, тогда возникает исключение Stackoverflow, попробуйте это – Deeptechtons 16 October 2012 в 05:24
  1. Создайте новый класс в вашей модели и свойствах LoginViewModel и RegisterViewModel:
    public class UserDefinedModel() 
    {
        property a1 as LoginViewModel 
        property a2 as RegisterViewModel 
    }
    
  2. Затем используйте UserDefinedModel в вашем представлении.
1
ответ дан Andrew 19 August 2018 в 00:23
поделиться
  • 1
    да, это работает для меня. то я ссылался на это следующим образом: (модель была указана в верхней части представления. В ней было 2 модели: профиль и файл электронной почты .... @ Html.DisplayNameFor (model = & gt; model.profile.BlackoutBegin) В контроллере я заполнил одну из моделей, используя @notso post ниже. Мне не нужно было заполнять другую, потому что я просто использовал ее для ввода. – JustJohn 19 April 2016 в 22:22

Я хочу сказать, что мое решение было похоже на ответ, представленный на этой странице stackoverflow: ASP.NET MVC 4, несколько моделей в одном представлении?

Однако в моем case, этот запрос linq, который они использовали в своем контроллере, не работал для меня.

Этот запрос:

var viewModels = 
        (from e in db.Engineers
         select new MyViewModel
         {
             Engineer = e,
             Elements = e.Elements,
         })
        .ToList();

Следовательно, «по вашему мнению, просто укажите, что вы использование коллекции моделей взглядов "тоже не помогло мне.

Однако небольшая вариация этого решения действительно работала для меня. Вот мое решение в случае, если это кому-то поможет.

Вот моя модель взгляда, в которой я знаю, что у меня будет только одна команда, но у этой команды может быть несколько плат (и у меня есть папка ViewModels в моей папке Models btw, следовательно, пространство имен):

namespace TaskBoard.Models.ViewModels
{
    public class TeamBoards
    {
        public Team Team { get; set; }
        public List<Board> Boards { get; set; }
    }
}

Теперь это мой контроллер. Это самое существенное отличие от решения в ссылке, упомянутой выше. Я создаю ViewModel для отправки по-другому.

public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            TeamBoards teamBoards = new TeamBoards();
            teamBoards.Boards = (from b in db.Boards
                                 where b.TeamId == id
                                 select b).ToList();
            teamBoards.Team = (from t in db.Teams
                               where t.TeamId == id
                               select t).FirstOrDefault();

            if (teamBoards == null)
            {
                return HttpNotFound();
            }
            return View(teamBoards);
        }

Тогда, на мой взгляд, я не указываю его как список. Я просто делаю «@model TaskBoard.Models.ViewModels.TeamBoards». Тогда мне нужно только для каждого, когда я перебираю доски команд. Вот мое мнение:

@model TaskBoard.Models.ViewModels.TeamBoards

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Team</h4>
    <hr />


    @Html.ActionLink("Create New Board", "Create", "Board", new { TeamId = @Model.Team.TeamId}, null)
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => Model.Team.Name)
        </dt>

        <dd>
            @Html.DisplayFor(model => Model.Team.Name)
            <ul>
                @foreach(var board in Model.Boards)
                { 
                    <li>@Html.DisplayFor(model => board.BoardName)</li>
                }
            </ul>
        </dd>

    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.Team.TeamId }) |
    @Html.ActionLink("Back to List", "Index")
</p>

Я довольно новичок в ASP.NET MVC, поэтому мне потребовалось немного времени, чтобы понять это. Поэтому я надеюсь, что этот пост поможет кому-то понять его проект за более короткий промежуток времени. : -)

94
ответ дан Community 19 August 2018 в 00:23
поделиться
  • 1
    Это был отличный способ справиться с этим, спасибо! Сделал то, что мне было нужно. – Todd Davis 22 March 2013 в 00:04
  • 2
    Я пробовал это, но если я использую EditorFor или HiddenFor (что идеально, что я хочу использовать), свойства модели не задаются при вызове методов контроллера Login1 / Login2. Предположительно, отображение @Name= игнорируется. Требует ли HiddenFor какой-либо другой трюк для этой ситуации? – Gary Chapman 20 November 2014 в 05:27
  • 3
    Это не сработает - вы не можете привязываться к модели при отправке формы – Stephen Muecke 27 November 2016 в 22:52
  • 4
    @Hamid Спасибо Хамиду, для новичка в MVC, это был самый простой ответ для меня. Спасибо. – Harold_Finch 12 May 2017 в 10:21
  • 5
    Как вы связали модель при отправке формы? – Mohammed Noureldin 16 April 2018 в 11:37

Добавьте этот ModelCollection.cs в свои модели

using System;
using System.Collections.Generic;

namespace ModelContainer
{
  public class ModelCollection
  {
   private Dictionary<Type, object> models = new Dictionary<Type, object>();

   public void AddModel<T>(T t)
   {
      models.Add(t.GetType(), t);
   }

   public T GetModel<T>()
   {
     return (T)models[typeof(T)];
   }
 }
}

Контроллер:

public class SampleController : Controller
{
  public ActionResult Index()
  {
    var model1 = new Model1();
    var model2 = new Model2();
    var model3 = new Model3();

    // Do something

    var modelCollection = new ModelCollection();
    modelCollection.AddModel(model1);
    modelCollection.AddModel(model2);
    modelCollection.AddModel(model3);
    return View(modelCollection);
  }
}

Вид:

enter code here
@using Models
@model ModelCollection

@{
  ViewBag.Title = "Model1: " + ((Model.GetModel<Model1>()).Name);
}

<h2>Model2: @((Model.GetModel<Model2>()).Number</h2>

@((Model.GetModel<Model3>()).SomeProperty
3
ответ дан Gytis Tenovimas 19 August 2018 в 00:23
поделиться

вы всегда можете передать второй объект в ViewBag или View Data.

1
ответ дан Nada N. Hantouli 19 August 2018 в 00:23
поделиться

простой способ сделать это

, мы можем сначала вызвать всю модель

@using project.Models

, а затем отправить вашу модель с помощью viewbag

// for list
ViewBag.Name = db.YourModel.ToList();

// for one
ViewBag.Name = db.YourModel.Find(id);

и в view

// for list
List<YourModel> Name = (List<YourModel>)ViewBag.Name ;

//for one
YourModel Name = (YourModel)ViewBag.Name ;

, тогда легко используйте это как Model

0
ответ дан Pnsadeghy 19 August 2018 в 00:23
поделиться

Используйте модель представления, которая содержит несколько моделей просмотров:

   namespace MyProject.Web.ViewModels
   {
      public class UserViewModel
      {
          public UserDto User { get; set; }
          public ProductDto Product { get; set; }
          public AddressDto Address { get; set; }
      }
   }

На ваш взгляд:

  @model MyProject.Web.ViewModels.UserViewModel

  @Html.LabelFor(model => model.User.UserName)
  @Html.LabelFor(model => model.Product.ProductName)
  @Html.LabelFor(model => model.Address.StreetName)
16
ответ дан smulholland2 19 August 2018 в 00:23
поделиться

Мне нужно сделать еще одно представление, которое содержит эти 2 представления?

Ответ: Нет

Нет ли другого способа такого как (без BigViewModel):

Да, вы можете использовать Tuple (придает магии возможность иметь несколько моделей).

Код:

 @model Tuple<LoginViewModel, RegisterViewModel>


    @using (Html.BeginForm("Login", "Auth", FormMethod.Post))
    {
     @Html.TextBoxFor(tuple=> tuple.Item.Name)
     @Html.TextBoxFor(tuple=> tuple.Item.Email)
     @Html.PasswordFor(tuple=> tuple.Item.Password)
    }


    @using (Html.BeginForm("Login", "Auth", FormMethod.Post))
     {
      @Html.TextBoxFor(tuple=> tuple.Item1.Email)
      @Html.PasswordFor(tuple=> tuple.Item1.Password)
     }
8
ответ дан sparkhee93 19 August 2018 в 00:23
поделиться
  • 1
    Разве это не правильно отобразило бы контроллер, принимавший форму? Я думал, что это будет искать "Item & quot; в вашем случае перед поиском & quot; name & quot ;. – SolidSnake4444 15 May 2017 в 04:16

Я бы рекомендовал использовать Html.RenderAction и PartialViewResults для этого; он позволит вам отображать одни и те же данные, но у каждого частичного вида все еще будет одна модель представления и устраняет необходимость в BigViewModel

. Таким образом, ваше представление содержит примерно следующее:

@Html.RenderAction("Login")
@Html.RenderAction("Register")

Где Login & amp; Register - оба действия в вашем контроллере, определенные следующим образом:

public PartialViewResult Login( )
{
    return PartialView( "Login", new LoginViewModel() );
}

public PartialViewResult Register( )
{
    return PartialView( "Register", new RegisterViewModel() );
}

Login & amp; Register будет пользовательским элементом управления, находящимся либо в текущей папке View, либо в общей папке, и хотел бы что-то вроде этого:

/Views/Shared/Login.cshtml: (или / Views / MyView /Login.cshtml)

@model LoginViewModel
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
    @Html.TextBoxFor(model => model.Email)
    @Html.PasswordFor(model => model.Password)
}

/Views/Shared/Register.cshtml: (или /Views/MyView/Register.cshtml)

@model ViewModel.RegisterViewModel
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
    @Html.TextBoxFor(model => model.Name)
    @Html.TextBoxFor(model => model.Email)
    @Html.PasswordFor(model => model.Password)
}

И там у вас есть действие одного контроллера, просмотр и просмотр файла для каждого действия с каждым полностью отличным и не зависящим друг от друга для чего-либо.

115
ответ дан TheRightChoyce 19 August 2018 в 00:23
поделиться
  • 1
    Это делает много смысла в плане проектирования, но с точки зрения эффективности, не нужно ли ему проходить 3 полных цикла цикла mvc? [Д0] stackoverflow.com/questions/719027/renderaction-renderpartial/… – Shawn Mclean 24 January 2011 в 18:30
  • 2
    Да, вы правы: это вызывает дополнительный полный цикл MVC для каждого RenderAction. Я всегда забываю свою часть фьючерсного пакета, так как мой проект всегда включает эту DLL по умолчанию. Это действительно зависит от предпочтений и требований приложений, если дополнительные циклы mvc стоят того разделения, которое он дает на стороне дизайна. Много раз вы можете кэшировать результаты RenderAction, поэтому единственным ударом, который вы принимаете, является небольшая дополнительная обработка через фабрику контроллера. – TheRightChoyce 24 January 2011 в 19:14
  • 3
    Я реализовал выше. Что мне не хватает? Пожалуйста, помогите: stackoverflow.com/questions/9677818/… – diegohb 13 March 2012 в 05:02
  • 4
    Святое дерьмо! Это отлично сработало для меня прямо из ворот. Я строю внутренний сайт с участием только пары пользователей ... так что эффективность не является реальной проблемой для меня. СПАСИБО! – Derek Evermore 14 August 2013 в 16:23
  • 5
    Чтобы использовать PartialView, нужно использовать фигурные скобки. – null 16 January 2018 в 16:07
Другие вопросы по тегам:

Похожие вопросы: