Unable to bind group of radiobuttons in mvc 5 - asp.net-mvc-5

I'm making a feedback form on mvc 5 and the feedback form consists of 10 questions having 5 selected answers each. Those selected answers are the group of radio buttons that I'm populating. But in post action method, the radio buttons are not getting bind. Below is my code.
Model.cs
public class FeedbackForm
{
public string Id { get; set; }
public Models.Questionnaire mquestions { get; set; }
public List<Questionnaire> Question { get; set; }
public Batches batches { get; set; }
public User user { get; set; }
public DateTime Datetime { get; set; }
}
public class Questionnaire
{
public string QuestionId { get; set; }
public string QuestionTitle { get; set; }
[Required]
public int? SelectedAnswer { get; set; } // for binding
public IEnumerable<QuestionnaireStatus> PossibleAnswers { get; set; }
}
public class QuestionnaireStatus
{
public string StatusId { get; set; }
public string StatusTitle { get; set; }
}
Controller.cs
public ActionResult Index()
{
List<Models.FeedbackForm> lstfeedback = new List<Models.FeedbackForm>();
Models.FeedbackForm form = new Models.FeedbackForm();
Context.FeedBackForm contFeedback = new Context.FeedBackForm();
Models.FeedbackForm vm = new Models.FeedbackForm();
form.Question = new List<Models.Questionnaire>();
form.Question = contFeedback.GetAllQuestionnaire();
for (int i = 0; i < form.Question.Count; i++)
{
lstfeedback.Add(new Models.FeedbackForm
{
Question = new List<Models.Questionnaire>()
{ new Models.Questionnaire
{
QuestionId = form.Question[i].QuestionId,
QuestionTitle = form.Question[i].QuestionTitle
,
PossibleAnswers = contFeedback.GetAllStatus()
},
}
});
}
return View(lstfeedback);
}
View.cshtml
#using (Html.BeginForm())
{
<table class="table">
<tr>
<th>
#*#Html.Display("Questions")*#
</th>
#for (int i = 0; i < Model.Count; i++)
{
for (int j = 0; j < Model[i].Question.Count; j++)
{
foreach (var item in Model[i].Question[j].PossibleAnswers)
{
<th>
#item.StatusTitle
</th>
}
break;
}
break;
}
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
#for (int j = 0; j < Model[i].Question.Count; j++)
{
<td>
#Html.DisplayFor(m=>Model[i].Question[j].QuestionTitle)
</td>
foreach (var item in Model[i].Question[j].PossibleAnswers)
{
<td>
#Html.RadioButtonFor(m => Model[i].Question[j].SelectedAnswer, item.StatusId, new { id = item.StatusId })
</td>
}
#Html.ValidationMessageFor(m => Model[i].Question[j].SelectedAnswer)
}
</tr>
}
</table>
<div class="form-group">
<div class="col-md-10">
<input type="submit" id="Attendance" value="Submit" class="btn btn-default" />
</div>
</div>
}

Related

ASP.Net MVC: How to show checkboxes selection in webgrid column after postback data

I have developed a tabular UI with webgrid. i am showing student information through webgrid. i am showing multiple checkboxes for hobbies in each row of webgrid. when i select hobbies and click submit button then i saw hobbies selection is not going to action.
i guess there is my mistake in view model class design. please have a look at my code and tell me which area i need to change in code.
i want all hobbies should go to action when i click submit button and selected hobbies also should post to action for each student. a student may have multiple hobbies selected.
here is my viewcode
#model MVCCRUDPageList.Models.StudentListViewModel
#{
ViewBag.Title = "Index";
}
<h2>Student View Model</h2>
#using (Html.BeginForm("Index", "WebGridMoreControls", FormMethod.Post))
{
var grid = new WebGrid(Model.Students, canSort: false, canPage: false);
var rowNum = 0;
var SelectedHobbies = 0;
<div id="gridContent" style=" padding:20px; ">
#grid.GetHtml(
tableStyle: "table",
alternatingRowStyle: "alternate",
selectedRowStyle: "selected",
headerStyle: "header",
columns: grid.Columns
(
grid.Column(null, header: "Row No", format: item => rowNum = rowNum + 1),
grid.Column("ID", format: (item) => #Html.TextBoxFor(m => m.Students[rowNum - 1].ID, new { #class = "edit-mode" })),
grid.Column("Name", format: (item) => #Html.TextBoxFor(m => m.Students[rowNum - 1].Name, new { #class = "edit-mode" })),
grid.Column("Country", format: (item) =>
#Html.DropDownListFor(x => x.Students[rowNum - 1].CountryID,
new SelectList(Model.Country, "ID", "Name", item.CountryID),
"-- Select Countries--", new { id = "cboCountry", #class = "edit-mode" })),
grid.Column(header: "Hobbies",
format: #<text>
Hobbies
#foreach (var hobby in Model.Hobbies)
{
<div class="checkbox">
<label>
#Html.HiddenFor(e => e.Hobbies)
<input type="checkbox"
name="Hobbies"
value="#hobby.ID" /> #hobby.Name
</label>
</div>
}
</text>)
))
<input type="submit" value="Submit" />
</div>
}
Action code
public class WebGridMoreControlsController : Controller
{
// GET: WebGridMoreControls
public ActionResult Index()
{
StudentListViewModel osvm = new StudentListViewModel();
return View(osvm);
}
[HttpPost]
public ActionResult Index(StudentListViewModel oStudentListViewModel)
{
return View(oStudentListViewModel);
}
}
View model code
public class StudentListViewModel
{
public IList<Student> Students { get; set; }
public List<Country> Country { get; set; }
public IList<Hobby> SelectedHobbies { get; set; }
public IList<Hobby> Hobbies { get; set; }
public StudentListViewModel()
{
Students = new List<Student>
{
new Student{ID=1,Name="Keith",CountryID=0,Hobby=0},
new Student{ID=2,Name="Paul",CountryID=2,Hobby=0},
new Student{ID=3,Name="Sam",CountryID=3,Hobby=0}
};
Country = new List<Country>
{
new Country{ID=1,Name="India"},
new Country{ID=2,Name="UK"},
new Country{ID=3,Name="USA"}
};
Hobbies = new List<Hobby>
{
new Hobby{ID=1,Name="Football"},
new Hobby{ID=2,Name="Hocky"},
new Hobby{ID=3,Name="Cricket"}
};
}
}
Model code
public class Student
{
public int ID { get; set; }
[Required(ErrorMessage = "First Name Required")]
public string Name { get; set; }
public int CountryID { get; set; }
public int Hobby { get; set; }
}
public class Country
{
public int ID { get; set; }
public string Name { get; set; }
}
public class Hobby
{
public int ID { get; set; }
public string Name { get; set; }
}
please help me to rectify view, viewmodel and model class code. thanks
Add a viewmodel for Hobby:
public class HobbyViewModel
{
public int ID { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
}
Modify your StudentListViewModel as following:
public class StudentListViewModel
{
public IList<Student> Students { get; set; }
public List<Country> Country { get; set; }
public IList<HobbyViewModel> Hobbies { get; set; }
public StudentListViewModel()
{
Students = new List<Student>
{
new Student{ID=1,Name="Keith",CountryID=0,Hobby=0},
new Student{ID=2,Name="Paul",CountryID=2,Hobby=0},
new Student{ID=3,Name="Sam",CountryID=3,Hobby=0}
};
Country = new List<Country>
{
new Country{ID=1,Name="India"},
new Country{ID=2,Name="UK"},
new Country{ID=3,Name="USA"}
};
Hobbies = new List<HobbyViewModel>
{
new HobbyViewModel{ID=1,Name="Football"},
new HobbyViewModel{ID=2,Name="Hocky"},
new HobbyViewModel{ID=3,Name="Cricket"}
};
}
Replace the foreach in the view as following:
#for (var i = 0; i < Model.Hobbies.Count; i++)
{
<div class="checkbox">
#Html.HiddenFor(m => m.Hobbies[i].ID)
#Html.CheckBoxFor(m => m.Hobbies[i].Checked)
#Html.LabelFor(m => m.Hobbies[i].Checked, Model.Hobbies[i].Name)
</div>
}

inherited classes and razor asp.net mvc 5

Good morning, I have a problem with returning my database information (generated using the EF 6 code-first method) for my View Razor. The issue is that I'm wanting to return the information from inherited classes in the View, but they are not available, only the properties of the base class are presented, not those of the dependent classes.
The following are the Model, Controller, and View classes used:
Class ClientModel
public class Client
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ClientId { get; set; }
[DataType(DataType.Date)]
public DateTime Birth { get; set; }
[Display(Name = "Telefone principal")]
public string Phone1 { get; set; }
[Display(Name = "Telefone Alternativo")]
public string Phone2 { get; set; }
public ICollection<OrcamentoContato> Contacts { get; set; }
public ICollection<Contrato> Contracts { get; set; }
}
Class FisicModel
public class PessoaFisica : Client
{
public TipoPessoa PersonType { get; set; }
[Required]
[Display(Name = "Nome completo*")]
[StringLength(250, ErrorMessage = "O campo é obrigatório.")]
public string Name { get; set; }
public string RG { get; set; }
[Required(ErrorMessage = "O campo CPF é obrigatório.")]
[StringLength(14)]
public string CPF { get; set; }
[Display(Name = "Filiação")]
public string Filiacao { get; set; }
[Display(Name = "Endereço")]
public string Address { get; set; }
}
Class JuridicModel
public class PessoaJuridica : Client
{
public TipoPessoa PersonType { get; set; }
[Required]
[Display(Name = "Razão Social*")]
[StringLength(200, ErrorMessage = "O campo é obrigatório.")]
public string SocialName { get; set; }
[Required]
[Display(Name = "CNPJ*")]
[StringLength(200, ErrorMessage = "O campo é obrigatório.")]
public string CNPJ { get; set; }
[Display(Name = "Inscrição Estadual")]
public string InscricaoEstadual { get; set; }
[Display(Name = "Inscrição Municipal")]
public string InscricaoMunicipal { get; set; }
[Display(Name = "Endereço")]
public string Address { get; set; }
public string ContactWith { get; set; }
}
Controller
public ActionResult Index()
{
var clients = db.Clients.ToList();
return View(clients);
}
Index View
#model IEnumerable<CabinePhoto.Models.Entidades.Client>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Birth)
</th>
<th>
#Html.DisplayNameFor(model => model.Phone1)
</th>
<th>
#Html.DisplayNameFor(model => model.Phone2)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Birth)
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone1)
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone2)
</td>
</tr>
}
IdentityModel
public DbSet<Client> Clients { get; set; }
public DbSet<PessoaFisica> PessoaFisica { get; set; }
public DbSet<PessoaJuridica> PessoaJuridica { get; set; }
All the information is stored in the same client table, since I'm using the form of inheritance by hierarchy, but in the view only the client model information is returned
I've been able to solve the problem. I'll leave here recorded what I did to solve the problem in respect to inheritance.
First, I created a ViewModel and put two ICollection properties, I modified the controller by adding the queries referring to the client table, but specifically bringing the required types and finally, I passed the ViewModel to the Index.cshtml and I used two foreachs to retrieve the information from According to the type specified, shown below:
ClientesiewModel.cs
public class ClientesViewModel
{
public IEnumerable<PessoaFisica> Fisica { get; set; }
public IEnumerable<PessoaJuridica> Juridica { get; set; }
}
controlle.cs
public ActionResult Index()
{
var cliente_fisico = db.Clientes.OfType<PessoaFisica>().ToList();
var cliente_juridico = db.Clientes.OfType<PessoaJuridica>().ToList();
var cliente = db.Clientes.ToList();
ClientesViewModel clientes = new ClientesViewModel()
{
Fisica = cliente_fisico,
Juridica = cliente_juridico
};
return View(clientes);
}
View Index.cshtml
#model CabinePhoto.ViewModels.ClientesViewModel
<table class="table">
<tr>
<th>
#Html.DisplayName("Nome")
</th>
<th>
#Html.DisplayName("Telefone")
</th>
<th>
#Html.DisplayName("Telefone 2")
</th>
<th></th>
</tr>
#if (Model.Fisica != null || Model.Juridica != null)
{
foreach (var fisica in Model.Fisica)
{
<tr>
<td>
#Html.DisplayFor(modelItem => fisica.NomeCompleto)
</td>
<td>
#Html.DisplayFor(modelItem => fisica.TelefonePrincipal)
</td>
<td>
#Html.DisplayFor(modelItem => fisica.TelefoneAlternativo)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = fisica.ClienteId }) |
#Html.ActionLink("Details", "Details", new { id = fisica.ClienteId }) |
#Html.ActionLink("Delete", "Delete", new { id = fisica.ClienteId })
</td>
</tr>
}
foreach (var juridica in Model.Juridica)
{
<tr>
<td>
#Html.DisplayFor(modelItem => juridica.PessoaContato)
</td>
<td>
#Html.DisplayFor(modelItem => juridica.CNPJ)
</td>
<td>
#Html.DisplayFor(modelItem => juridica.TelefonePrincipal)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = juridica.ClienteId }) |
#Html.ActionLink("Details", "Details", new { id = juridica.ClienteId }) |
#Html.ActionLink("Delete", "Delete", new { id = juridica.ClienteId })
</td>
</tr>
}
}
</table>
Thanks for the help previously assigned
Suppose you have a variable like this in your controller.
Client c = new Client();
If you later wrote
c.ClientId = 1;
it would work perfectly.
Similarly, if you wrote
PessoaFisica p = new PessoaFisica ();
and later
p.Name = "abc";
it would also work.
However, if you wrote
Client c = new PessoaFisica();
c.Name = "abc";
It will fail to compile.
Along the same lines
#model IEnumerable <CabinePhoto.Models.Entidades.Client>
means static type of your Model is a collection of Client objects, it will only allow you to bind to properties defined in Client class.
Entity Framework actually returns the correct types, but you're effectively upcasting everything to Client by the variable type you're storing into and the model definition of the view. Essentially, you just need to cast to the right type. Unfortunately, there's no way to just know what type it should be after it's been upcasted. You'll have to conditionally check:
if (item is PessoaFisica)
{
var pessoaFiscica = (PessoaFisica)item;
// now you can access those derived typed properties off of `pessoaFiscica`
}
You can also use as and rely on the fact that it returns null when something can't be casted:
var pessoaFiscica = item as PessoaFisica;
if (pessoaFiscica != null)
{
// access PessoaFiscica properties
}
With C# 7.0, you can use the pattern matching syntax to streamline it a little:
if (item is PessoaFiscica pessoaFiscica)
{
// use `pessoaFiscica`
}
The pattern matching syntax also allows you use switch blocks, which may make things much easier on you:
switch (item)
{
case PessoaFisica pessoaFisica:
// do something with `PessoaFisica` instance
break;
case PessoaJuridica pessoaJuridica:
// do something with `PessoaJuridica` instance
break;
default:
// do something with generic `Client` instance
break;
}

Dropdownlist in MVC 5

I want to display multiple DropDownList MVC5. I have corresponding classes for the same. Kindly advise for the same. I am totally new to MVC.Value (SysId) needs to stored in database and description will be displayed in page. There are 4 dropdownlists in web page. All classes have same properties.
Kindly help for the same ..
public ActionResult Registration()
{
RegistrationClass obj = new RegistrationClass();
obj = obj.getAllDropdown();
return View(obj);
}
public class RegistrationClass
{
[Required(ErrorMessage = "Please enter Name")]
[StringLength(50, ErrorMessage = "Name can not be more than 50 characters ")]
[DisplayName("Name")]
public string name { get; set; }
[Required(ErrorMessage = "Please select Gender")]
[DisplayName("Gender")]
public string gender { get; set; }
[Required(ErrorMessage = "Please enter Date of Birth")]
[DisplayName("Date of Birth")]
[DataType(DataType.Date,ErrorMessage = "Invalid Date ")]
public DateTime dob { get; set; }
[DisplayName("Caste")]
public List<Caste> lcaste { get; set; }
public int cast_id { get; set; }
public RegistrationClass getAllDropdown()
{
RegistrationClass obj = new RegistrationClass();
Connection cobj = new Connection();
string strConn = cobj.getConnectionString();
SqlConnection con = new SqlConnection(strConn);
SqlCommand cmd = new SqlCommand("proc_get_preference_dropdown", con);
SqlDataAdapter ada = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
ada.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count;i++ )
{
if (ds.Tables[0].Rows[i]["code"].ToString() == "04") // Set Caste Preference
{
lcaste = new List<Caste>();
Caste obj1 = new Caste();
obj1.decription = ds.Tables[0].Rows[i]["description"].ToString();
obj1.sysId = Convert.ToInt32(ds.Tables[0].Rows[i]["id"]);
//obj1.isChecked = "N";
lcaste.Add(obj1);
obj.lcaste = lcaste;
continue;
}
}
}
return obj;
}
public class Caste
{
public int sysId { get; set; }
public string decription { get; set; }
public string isChecked { get; set; }
}
}
#model Matrimony.Models.RegistrationClass
<tr>
<td>
#Html.LabelFor(model => model.subcaste)
</td>
<td>
#Html.DropDownListFor(model => model.cast_id, new SelectList(Model.lcaste))
</td>
</tr>
Finally I resolved this by adding simple option tags.
<td>
<select name="cast_id">
<option value="0">--Select--</option>
#for (int i = 0; i < Model.lcaste.Count; i++)
{
<option value=#Model.lcaste[i].sysId>#Model.lcaste[i].decription</option>
}
</select>
</td>
The name property of select will get the selected item's value in post method. Accordingly we can handle it in controller. I also added property in my model class to store value as
public int cast_id { get; set; }
public List<Caste> lcaste { get; set; }

dynamically create textbox and save data MVC

I am new to MVC. I want to dynamically create textboxes upon user click.
<script>
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var colCount = table.rows[0].cells.length;
for(var i=0; i<colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
switch(newcell.childNodes[0].type) {
case "text":
newcell.childNodes[0].value = "";
break;
case "checkbox":
newcell.childNodes[0].checked = false;
break;
case "select":
newcell.childNodes[0].selectedIndex = 0;
clear_attrib();
break;
}
}
else {
alert("Cannot add another row.");
}
}
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
for(var i=0; i<rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox && true == chkbox.checked) {
if(rowCount <= 1) {
alert("Cannot delete all the rows.");
break;
}
table.deleteRow(i);
rowCount--;
i--;
}
}
}catch(e) {
alert(e);
}
}
and the Razor
<table class="table" id="AddSchedule">
<tr>
<td><input type="checkbox" name="chk[]" class="checkbox_style" /></td>
<td>#Html.EditorFor(model => model.Schedule, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Schedule, "", new { #class = "text-danger" })
</td>
<td>#Html.EditorFor(model => model.Room, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Room, "", new { #class = "text-danger" })
</td>
<td>#Html.EditorFor(model => model.Subject, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Subject, "", new { #class = "text-danger" })
</td>
</tr>
the adding and removing of textboxes is OK. But I don't know how to save the data in the database. This is my controller
public ActionResult Create(EmployeeViewModel employeeViewModel)
{
if (ModelState.IsValid)
{
var emp = db.Employee.Create();
emp.ID = employeeViewModel.ID;
emp.LastName = employeeViewModel.LastName;
emp.FirstName = employeeViewModel.FirstName;
db.Employee.Add(emp);
var sched = db.FacultySchedule.Create();
sched.Schedule = employeeViewModel.Schedule;
sched.Room = employeeViewModel.Room;
sched.Subject = employeeViewModel.Subject;
db.FacultySchedule.Add(sched);
db.SaveChanges();
}
I tried using foreach but it still save only the first value, so i removed it... I think I'm missing something in the mark-up... like adding [] to make it an array just like in PHP. And I don't know how to fix it in the controller.
How can I fix the mark-up and the loop for in the controller for saving? Thanks.
Edit
this is the viewmodel
public class EmployeeViewModel
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Schedule { get; set; }
public string Room { get; set; }
public string Subject { get; set; }
public virtual IEnumerable<FacultySchedule> FacultySchedule { get; set; }
}
and these are the domain model
public partial class Employee
{
public Employee()
{
FacultySchedule = new HashSet<FacultySchedule>();
}
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public virtual ICollection<FacultySchedule> FacultySchedule { get; set; }
}
public partial class FacultySchedule
{
public FacultySchedule()
{
Substitution = new HashSet<Substitution>();
}
public int ID { get; set; }
public int EmployeeID { get; set; }
public string Schedule { get; set; }
public string Room { get; set; }
public string Subject { get; set; }
public virtual Employee Employee { get; set; }
}

Orchard Projection Page Default View

I am using Orchard 1.8 and have created a new content type (called PressRelease), query for the results and projection to view the query with a custom template (using URL Alternates in the format List-ProjectionPage-url-PressRelease.cshtml) and all of that is working fine.
The one part that has me stumped is, if I use The Theme Machine as my theme (untouched), this projection view will show up in an unordered list with the corresponding AutoRoute links to the individual ContentItem entities, their metadata and so on. I'm trying to figure out how I access things such as the AutoRoute URL for a specific item, the metadata (create/publish dates) and so on for use with things like a Facebook Share button. Essentially I'm trying to recreate that default view, albeit with customizations.
Here is the code for List-ProjectionPage-url-PressRelease.cshtml:
#using Orchard.Utility.Extensions;
#using System.Linq
#functions
{
public class PressRelease
{
public PressRelease()
{
this.Attachments = new List<Attachment>();
}
public string Title { get; set; }
public string Source { get; set; }
public DateTime PublishDate { get; set; }
public string Body { get; set; }
public List<Attachment> Attachments { get; set; }
}
public class Attachment
{
public string Filename { get; set; }
public string Path { get; set; }
}
}
#{
//add list of dynamic objects to strongly typed class
var releases = new List<PressRelease>();
foreach (var item in #Model.Items)
{
var release = new PressRelease
{
Title = item.ContentItem.TitlePart.Title,
Source = item.ContentItem.PressRelease.Source.Value,
PublishDate = item.ContentItem.PressRelease.Date.DateTime,
Body = item.ContentItem.BodyPart.Text
};
//load attachment(s) to class
var attachments = (Orchard.MediaLibrary.Fields.MediaLibraryPickerField)item.ContentItem.PressRelease.Attachment;
if (attachments.MediaParts.Count() > 0)
{
foreach (var part in attachments.MediaParts)
{
release.Attachments.Add(new Attachment { Filename = part.FileName, Path = part.MediaUrl });
}
}
releases.Add(release);
}
}
#{
foreach (var item in releases)
{
<div class="press-release">
<div class="press-release-title">#item.Title</div>
<div class="press-release-meta">
<span class="press-release-source">Source: #item.Source</span>
#if (item.PublishDate != DateTime.MinValue)
{
<span class="press-release-date">#item.PublishDate.ToShortDateString()</span>
}
</div>
#if (item.Attachments.Count() > 0)
{
<div class="press-release-attachments">
<span class="press-release-attachments-title">Attached: </span>
#foreach (var attachment in item.Attachments)
{
var linkText = attachment.Filename;
var url = attachment.Path;
#Html.Link(linkText, url);
if (attachment != item.Attachments.Last())
{
<span>, </span>
}
}
</div>
}
<div class="press-release-body">
<p>#Html.Raw(item.Body.Replace("\r\n", "<br />"))</p>
</div>
</div>
<div class="social">
<!-- ** This is where I need AutoRoute URL so I can do FB share link **-->
<div class="fb-share-button" data-href="" data-type="button_count"></div>
</div>
if (item != releases.Last())
{
<hr />
}
}
}
Thoughts?
Utilizing the Shape Tracer (in conjunction with #Bertrand's assistance in the comments above) helped me get to where I need. Here is the final layout code I went with (which has some super hacky stuff in it):
#using Orchard.Utility.Extensions;
#using System.Linq
#functions
{
public class PressRelease
{
public PressRelease()
{
this.Attachments = new List<Attachment>();
}
private string _NavigateUrl = string.Empty;
public string Title { get; set; }
public string Source { get; set; }
public DateTime PublishDate { get; set; }
public string Body { get; set; }
public List<Attachment> Attachments { get; set; }
public string NavigateUrl
{
get { return string.Format("{0}://{1}/{2}", HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Authority, _NavigateUrl); }
set { this._NavigateUrl = value; }
}
}
public class Attachment
{
public string Filename { get; set; }
public string Path { get; set; }
}
}
#{
//add list of dynamic objects to strongly typed class
var releases = new List<PressRelease>();
foreach (var item in #Model.Items)
{
var release = new PressRelease
{
Title = item.ContentItem.TitlePart.Title,
Source = item.ContentItem.PressRelease.Source.Value,
PublishDate = item.ContentItem.PressRelease.Date.DateTime,
//this is super hacky to get a chopped version of the HTML submitted for a summary
Body = item.ContentItem.BodyPart.Text,
NavigateUrl = item.ContentItem.AutoroutePart.Path
};
//load attachment(s) to class
var attachments = (Orchard.MediaLibrary.Fields.MediaLibraryPickerField)item.ContentItem.PressRelease.Attachment;
if (attachments.MediaParts.Count() > 0)
{
foreach (var part in attachments.MediaParts)
{
release.Attachments.Add(new Attachment { Filename = part.FileName, Path = part.MediaUrl });
}
}
releases.Add(release);
}
}
#{
foreach (var item in releases)
{
<div class="press-release">
<div class="press-release-title">#item.Title</div>
<div class="press-release-meta">
<span class="press-release-source">Source: #item.Source</span>
#if (item.PublishDate != DateTime.MinValue)
{
<span class="press-release-date">#item.PublishDate.ToShortDateString()</span>
}
</div>
#if (item.Attachments.Count() > 0)
{
<div class="press-release-attachments">
<span class="press-release-attachments-title">Attached: </span>
#foreach (var attachment in item.Attachments)
{
#attachment.Filename
if (attachment != item.Attachments.Last())
{
<span>, </span>
}
}
</div>
}
<div class="press-release-body">
#{
var body = new HtmlString(Html.Excerpt(item.Body, 200).ToString().Replace(Environment.NewLine, "</p>" + Environment.NewLine + "<p>"));
<p>#body (read more)</p>
}
</div>
</div>
<div class="social">
<div class="fb-share-button" data-href="#item.NavigateUrl" data-type="button_count"></div>
</div>
if (item != releases.Last())
{
<hr />
}
}
}

Resources