Проблемы с бритвой.net mvc 4 Html.checkboxfor
У меня есть две проблемы с вышеупомянутой сюжетной линией на его использовании.
У меня есть две строго типизированные модели, которые мне нужно использовать в одном представлении. Причина, по которой мне нужны две разные модели, заключается в том, что считываемые данные поступают из двух разных баз данных, поэтому мне нужно было иметь модель данных edmx (Entity Framework) для каждой из них.
Я просто хочу внести динамический список "шаблонов" и "поручителей". Количество возвращаемых предметов, очевидно, может измениться.
Проблема 1: Я хочу установить для каждого флажка "флажок" и установить его имя для отображения. При этом я не знаю, правильный ли синтаксис или нет так, как я его настроил, хотя второй не дает мне ошибки компиляции во время разработки.
Проблема 2. Другая проблема, с которой я сталкиваюсь, заключается в том, что мне нужно использовать разные модели для каждого набора флажков. Но когда я устанавливаю модель во втором наборе флажков, первая модель игнорируется (что имеет смысл, потому что она последняя).
Как я могу успешно использовать каждую из моделей в одном представлении, чтобы правильно установить флажки?
Вот код:
<tr>
<td colspan="5">
<b>@Html.Label("lbl_Templates", "Templates:")</b>
</td>
</tr>
<tr>
@model IEnumerable<PDFConverterModel.PDFTemplate>
@foreach (var item in Model)
{
<td>
@Html.CheckBoxFor(model => true, item.TemplateName)
</td>
}
</tr>
<tr>
<td colspan="5">
<b>@Html.Label("lbl_Guarantor", "Guarantor(s):")</b>
</td>
</tr>
<tr>
@model IEnumerable<PDFConverterModel.tGuarantor>
@foreach (var item in Model)
{
<td>
@Html.CheckBoxFor(model => true, item.GuarantorFirstName + " " + item.GuarantorLastName)
</td>
}
</tr>
Кстати, правильно ли используется синтаксически использование метки, где первый параметр - это идентификатор метки, а второй - значение, которое отображается?
Часть решения: я почти на месте... У меня проблема с получением индексации свойств, которые я хочу показать через помощник CheckBoxFor Html в представлении (которое я до сих пор не использовал)...
Если бы вы могли помочь мне с этой последней частью, я был бы очень признателен...
Вы можете видеть, что я создал представленный ниже ViewModel (класс, с которым я работаю, это класс ViewModelTemplate_Guarantors).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PDFConverterModel;
namespace PDFConverterModel.ViewModels
{
public class ViewModelTemplate
{
public int SelectedTemplateId { get; set; }
public IEnumerable<PDFTemplate> Templates { get; set; }
}
public class ViewModelGuarantors
{
public int SelectedGuarantorId { get; set; }
public IEnumerable<tGuarantor> Guarantors { get; set; }
}
public class ViewModelDepartment
{
public int SelectedDepartmentId { get; set; }
public IEnumerable<Department> Departments { get; set; }
}
public class ViewModelTemplate_Guarantors
{
public int SelectedTemplateId { get; set; }
public IEnumerable<PDFTemplate> Templates { get; set; }
public int SelectedGuarantorId { get; set; }
public IEnumerable<tGuarantor> Guarantors { get; set; }
}
}
Ниже приведен метод бизнес-кода, который я создал в отдельной библиотеке DLL в клиентском проекте, который заполняет модель.
public ViewModelTemplate_Guarantors SelectViewModelTemplate_Guarantors(int LoanId, string LoanTypeId, int DepartmentId)
{
try
{
var model = new ViewModelTemplate_Guarantors();
using (PDFService03Entities DbContext1 = new PDFService03Entities())
{
DbContext1.Database.Connection.Open();
IEnumerable<PDFTemplate> temps = DbContext1.PDFTemplates.Where(p => p.LoanTypeId == Convert.ToInt32(LoanTypeId) && p.DepartmentId == DepartmentId).FromCache(CachePolicy.WithSlidingExpiration(TimeSpan.FromSeconds(30)));
model.Templates = temps.Select(x => new PDFTemplate
{
TemplateId = x.TemplateId.ToString(),
TemplateName = x.TemplateName
});
}
using (VisionEntities DbContext2 = new VisionEntities())
{
DbContext2.Database.Connection.Open();
IEnumerable<tGuarantor> guars = DbContext2.tGuarantors.Where(p => p.ApplicationNum == LoanId).FromCache(CachePolicy.WithSlidingExpiration(TimeSpan.FromSeconds(30)));
model.Guarantors = guars.Select(x => new tGuarantor
{
ApplicationNum = x.ApplicationNum,
GuarantorFirstName = x.GuarantorFirstName,
GuarantorLastName = x.GuarantorLastName
});
}
return model;
}
catch (Exception ex)
{
throw ex;
}
}
Ниже приведена часть метода Contoller Action, который вызывает приведенный выше код:
ViewModelTemplate_Guarantors tg = db.SelectViewModelTemplate_Guarantors(Convert.ToInt32(loanID), loanType, Convert.ToInt32(selectedVal));
Ниже, где у меня есть моя проблема в View...
Так как я передаю обратно объект IEnumerable, если я смог отправить вложения сюда, у меня есть 4 снимка экрана, которые показывают, как я использую свой вид.
Достаточно сказать, что скриншоты ясно показывают, что шаблоны и гаранты обнаруживаются. Оба они имеют тип IEnumerable ViewModelTemplate_Guarantors.Templates и.Guarantors соответственно.
Я просто хочу добавить индекс возвращаемого элемента, но получаю ошибку компиляции во время разработки:
Msgstr "Невозможно применить индексирование с помощью [ ] к выражению типа 'System.Collections.Generic.IEnumerable" и tGuarantor соответственно.
Назовите это "101 программирование", если я не утомлен работой над этим, но я должен иметь возможность применить индексную переменную для вышеупомянутой коллекции, чтобы вернуть соответствующий элемент, если я полностью не забыл что-то....
Что я делаю не так внизу???
Вот мой взгляд:
@model IEnumerable<PDFConverterModel.ViewModels.ViewModelTemplate_Guarantors>
@{
ViewBag.Title = "BHG :: PDF Generator";
int ctr = 0;
}
<h2>@ViewBag.Message</h2>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
<tr>
<td>
<label for="txtLoanID">Loan ID :</label>
@(Html.Kendo().IntegerTextBox()
.Name("txtLoanID")
.Placeholder("Enter LoanID")
)
<td colspan="3">
<input type="submit" id="btnRefresh" value='Refresh' />
</td>
</tr>
<tr>
<td><@Html.Label("lblLoanType1", "Loan Type : ")</td>
<td><@Html.Label("lblLoanType2", "SBA")</td>
<td></td>
<td>
<label for="ddlDept">Department:</label>
@(Html.Kendo().DropDownList()
.Name("ddlDept")
.DataTextField("DepartmentName")
.DataValueField("DepartmentID")
.Events(e => e.Change("Refresh"))
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetDepartments", "Home");
});
})
)
</td>
</tr>
<tr>
<td colspan="5">
<b>@Html.Label("lbl_Templates", "Templates:")</b>
</td>
</tr>
<tr>
@ctr = 0;
@foreach (var item in Model)
{
<td>
@Html.CheckBoxFor(model => item.Templates[ctr].TemplateName)
@ctr = ctr + 1;
@Html.LabelFor(model => item.Templates[ctr].TemplateName)
</td>
}
</tr>
<tr>
<td colspan="5">
<b>@Html.Label("lbl_Guarantor", "Guarantor(s):")</b>
</td>
</tr>
<tr>
@ctr = 0;
@foreach (var item in Model)
{
<td>
@Html.CheckBoxFor(model => item.Guarantors[ctr].GuarantorFirstName + " " + item.GuarantorLastName)
@ctr = ctr + 1;
@Html.LabelFor(model => item.Guarantors[ctr].GuarantorFirstName + " " + item.GuarantorLastName)
</td>
}
</tr>
<tr>
<td colspan="2"></td>
<td>
@*@using (Html.BeginForm("GeneratePDF", "Home", new { @loanID = loanID }, FormMethod.Post))
{
<input type="submit" id="btnGeneratePDF" value='Generate PDF' />
}*@
</td>
<td colspan="2"></td>
</tr>
<tr>
<td colspan="5">
<b>@ViewBag.Error</b>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</form>
<script type="text/javascript">
$(document).ready(function () {
$("#ddlDept").prepend("<option value='All' selected='selected'></option>");
});
var txtLoanID;
$("#btnRefresh").click(function () {
Refresh();
});
function Refresh() {
var txtLoanID = $("#txtLoanID").val();
if (txtLoanID != "") {
$.post('/Home/Refresh', { loanID: $('#txtLoanID').val(), loanType: $('#lblLoanType2').val, selectedVal: $("#ddlDept option:selected").text() }, function (data) {
data.success;
if (data.success == true) {
if (data.templist == true) {
//show the templates
$("#lbl_Templates").visible = true;
$("#btnGeneratePDF").visible = true;
}
if (data.guarlist == true) {
//show the guarantors
$("#lbl_Guarantor").visible = true;
$("#btnGeneratePDF").visible = true;
}
if ((data.templist == true) && (data.guarlist == true)) {
$("#btnGeneratePDF").visible = true;
}
else {
$("#btnGeneratePDF").visible = false;
}
}
else {
$("#btnGeneratePDF").visible = false;
//hide the templates
$("#lbl_Templates").visible = false;
$("#btnGeneratePDF").visible = false;
//hide the guarantors
$("#lbl_Guarantor").visible = false;
$("#btnGeneratePDF").visible = false;
}
});
}
else {
alert("Please enter a Loan ID.");
}
}
$("#form1").validate({
event: "submit",
rules: {
txtLoanID: {
required: true
}
},
messages: {
txtLoanID: {
required: ' Please enter a Loan ID. '
}
}
});
</script>
2 ответа
Вы можете использовать Html.Checkbox вместо Html.CheckBoxFor, если вам действительно необходимо выполнить задачу создания элемента управления для значения, которого нет в вашей модели.
Это позволяет вам программно указать имя, значение и свойство IsChecked.
Или сделайте так, как предлагает другой ответ, и создайте свойство GarantorFullName для вашей модели.
CheckBoxFor ожидает точное имя одного свойства в модели.
Вы не можете поставить галочку для item.GuarantorFirstName + " " + item.GuarantorLastName
Только один элемент, например, только item.GuarantorFirstName
если вам нужны оба одновременно, укажите в вашей модели полное имя свойства, которое содержит item.GuarantorFirstName + " " + item.GuarantorLastName
CheckBox Для указания на item.Fullname