Я знаю, что это довольно просто, и часто спрашивают, но соединение всего этого вместе для меня все еще ново.
Каждый Invoice
имеет идентификатор:
Модель
public class Invoice
{
public int Id { get; set; }
}
Я использую viewModel
, чтобы заполнить список выборов для выпадающего списка, который прекрасно работает. После возврата в новое представление, Main
, viewModel
также используется для захвата InvoiceId выбора из выпадающего списка.
ViewModel
public class MainPageViewModel
{
public int InvoiceId { get; set; }
public IEnumerable<Invoice> Invoices { get; set; }
}
Контроллер
public ActionResult Index()
{
var userId = User.Identity.GetUserId();
var viewModel = new MainPageViewModel
{
Invoices = _context.Invoices.Where(i => i.User.Id == userId).ToList();
};
return View("Main", viewModel);
}
И я хочу использовать razor: @Html.BeginForm()
для маршрутизации на URL {controller}/{action}/{id}
, используя этот cshtml:
View
@model SubSheets.ViewModels.MainPageViewModel
@using (Html.BeginForm(
action: "WorkSummary",
controller: "Invoices",
routeValues: new { id = Model.InvoiceId }))
{
@Html.AntiForgeryToken()
<div class="form-group">
<div class="col-md-10">
@Html.DropDownListFor(
expression: m => m.InvoiceId,
new SelectList(
Model.Invoices,
dataValueField: "Id",
dataTextField: "Name"
)
)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Go To Invoice" class="btn btn-
default" />
</div>
</div>
}
А затем просто используйте соглашение в новом представлении, которое правильно строит URL. Проблема в id == 0
независимо от того, какой выбор выбран.
public ActionResult WorkSummary()
{
return View();
}
Насколько я понимаю, лямбда-выражение в DropDownListFor
определяет хук данных в объекте viewModel
, а dataValueField
SelectList
захватывает Id
выбора в этом случае и присваивает его выражение.
Я предполагал, что он выполнит задание и передаст Id
в viewModel
и передаст его в routeValues
после отправки формы, однако он пропустит 0
вместо правильного Id
.
Если я загружаю новый вид с помощью viewModel, я могу правильно отобразить id
, используя бритву на странице. E.g.:
@using SubSheets.ViewModels.MainPageViewModel
<p>@Model.InvoiceId.ToString()</p>
Что мне здесь не хватает?
Edit:
Я попытался переместить раскрывающийся список за пределы формы и создать отдельную кнопку отправки:
<a href="@Url.Action("WorkSummary", "Invoices", new {id = Model.InvoiceId })"><button class="btn btn-default">Button</button></a>
Мне кажется, что я пытаюсь протолкнуть квадратный колышек в круглое отверстие. Я ошибаюсь?
Edit2
Ну, я придумала другое решение. Понимая, что я хочу использовать помощник Url
, я использовал Bootstrap, чтобы сделать каждый выбор кликабельным, что в любом случае намного проще.
<div class="btn-group">
<button
type="button"
class="btn btn-default dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
Select Invoice <span class="caret"></span>
</button>
<ul class="dropdown-menu">
@foreach (var invoice in Model.Invoices)
{
<li><a href="@Url.Action(
"WorkSummary",
"Invoices",
new {id = invoice.Id},
null)">
@invoice.Name
</a></li>
}
</ul>
</div>
затем передайте id
в контроллер, запросите базу данных и верните правильную запись с правильным URL. Можно потратить полдня на то, что на сборку у меня ушло 5 минут, верно?