Posting ul elements to a controller - c#

I have a simple email form with TO, CC, BCC and another field for an attachment location i have the view working but i cant workout how to get all 3 ul lists to post to the controller
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
<label class="control-label col-md-2">To</label>
<div class="col-md-10">
<ul name="To" id="email-To"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Cc</label>
<div class="col-md-10">
<ul name="CC" id="email-Cc"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Bcc</label>
<div class="col-md-10">
<ul name="Bcc" id="email-Bcc"></ul>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FileName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FileName, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="pull-right">
<button type="submit" class="btn btn-success btn-xs">
<i class="fa fa-save"></i> Create
</button>
</div>
</div>
}
The model:
public System.Guid ID { get; set; }
public string To { get; set; }
public string CC { get; set; }
public string BCC { get; set; }
public string FileName { get; set; }
It will post the filename but not the ul's im guessing i would need to do some kind of json post for this kind of thing im not two sure?

Related

How to validate an input out of model in MVC5

I have been trying to validate an input which is not properly in the model. I have the following code:
#using (Html.BeginForm("Address", "Locations", FormMethod.Post, new { id =
"mainForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="card shadow-sm">
<div class="card-header">
<h3 class="card-title">
Step 1
</h3>
<label>
Search for service location(s)
</label>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label for="exampleInputEmail1">Zip code: <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="ZipCode" name="ZipCode" autocomplete="off" autofocus />
#Html.ValidationMessage("ZipCode")
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="exampleInputPassword1">House number:</label>
<input type="text" class="form-control" id="HouseNumber" name="HouseNumber" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="exampleInputPassword1">City:</label>
<input type="text" class="form-control" id="City" name="City" />
</div>
</div>
</div>
</div>
<div class="card-footer">
<div class="row">
<div class="col-md-12">
<button class="btn btn-primary" type="submit">
<i class="fas fa-search"></i>
Search for location(s)
</button>
</div>
</div>
</div>
</div>
}
The mode is
#model PagedList.IPagedList<iCRM.Models.Address>
But the name which I gave to the input is not in the model. However the validation is not working at all. And the POST is ignoring my validation.
Can somebody help me out, what I am doing wrong?
Thanks in advance.
You have 2 options.
add ZipCode to the model class iCRM.Models.Address.
Write custom validation with Request.Forms["ZipCode"] and Javascript handler on client side. (#Html.ValidationMessage("ZipCode") you can not call)
This is idea based on option 2 but not a definite answer.
Controller
[HttpGet]
public ActionResult Address()
{
return View();
}
[HttpPost]
public ActionResult Address(AddressModel model)
{
if (String.IsNullOrEmpty(Request.Form["ZipCode"]))
{
ViewBag.ValidationForZipCode = "Problem with ZipCode";
}
return View();
}
View
#model WebApplication1.Models.AddressModel
#{
ViewBag.Title = "Address";
string strValidationForZipCode = "";
if (ViewBag.ValidationForZipCode != null)
{
strValidationForZipCode = ViewBag.ValidationForZipCode.ToString();
}
}
<h2>Address</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken();
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="pull-right">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</div>
<table>
<tr>
<td>
<div class="form-group">
#Html.LabelFor(model => model.Address1, htmlAttributes: new {
#class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address1, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address1, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label for="exampleInputEmail1">Zip code: <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="ZipCode" name="ZipCode" autocomplete="off" autofocus />
<input type="hidden" id="hdValidationForZipCode" name="hdValidationForZipCode" value="#strValidationForZipCode" />
</div>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</div>
}
<script type="text/javascript">
var str1 = document.getElementById("hdValidationForZipCode").value; //$('#hdValidationForZipCode').val();
if (str1 != "")
alert(str1);
</script>
Model
using System.ComponentModel.DataAnnotations;
namespace WebApplication1.Models
{
public class AddressModel
{
[Required]
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
}

Mark Radio Button as Selected ASP.NET MVC5 C#

I have a page written using some fake data in my controller, to render some mock data in my view. Here is the code I have:
Model
Data View Model
[Required]
[Display(Name = "Is this a remix?")]
public bool IsRemix { get; set; }
[Required]
[Display(Name = "Does this song contain sample(s)?")]
public bool ContainsSample { get; set; }
I had this in my ViewModel
public bool IsRemix { get; set; }
public bool ContainsSample { get; set; }
Controller
model.Songs = songs;
model.SongTitle = "Darkside of the Moon";
model.AlternativeSongTitle = "Wish You Were Here";
model.DurationMinutes = 3;
model.DurationSeconds = 57;
model.IsRemix = true;
model.ContainsSample = false;
View
<div class="form-group">
<label class="control-label col-md-4 pull-left" for="SongTitle">Is a Remix</label>
<div class="col-md-8">
<div class="admin-form theme-primary">
<div class="radio-custom radio-primary mt10 mr10 pull-left">
#Html.RadioButtonFor(m => m.IsRemix, true, new { #class = "control-label col-md-4" })
<label for="IsRemixYes">Yes</label>
</div>
<div class="radio-custom radio-primary mt10 pull-left">
#Html.RadioButtonFor(m => m.IsRemix, true, new { #class = "control-label col-md-4" })
<label for="IsRemixNo">No</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-4 pull-left" for="SongTitle">Contains Sample</label>
<div class="col-md-8">
<div class="admin-form theme-primary">
<div class="radio-custom radio-primary mt10 mr10 pull-left">
#Html.RadioButtonFor(m => m.ContainsSample, true, new { #class = "control-label col-md-4" })
<label for="ContainsSampleYes">Yes</label>
</div>
<div class="radio-custom radio-primary mt10 pull-left">
#Html.RadioButtonFor(m => m.ContainsSample, true, new { #class = "control-label col-md-4" })
<label for="ContainsSampleNo">No</label>
</div>
</div>
</div>
</div>
I am unsure how to get the radio buttons to be pre-selected.

Using dynamic models in partials using Razor syntax is throwing an error

I will be using the same partial across many different pages and the only thing that will be different is reference to the model (#model ...). I tried using "#model dynamic" so I can reference model in view, however lambdas that are in my partial that are referencing specific properties are throwing the following error:
"An expression tree may not contain a dynamic operation"
caused by the following reference to model:
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
How do structure my code or create a model reference that will work dynamically so that I can reference each specific model instance in my view pages? I tried many solutions online and nothing has worked so far. Below is my partial and view. Any help would be greatly appreciated!!!
Partial:
#model dynamic
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="container creative-containter-top">
<div class="row">
<div class="col-sm-offset-2 col-sm-8">
<div class="form-horizontal">
<div class="panel panel-primary">
<div class="panel-height pane panel-heading text-center">
<h3>#ViewBag.Title</h3>
</div>
<div class="panel-body">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Code, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Code, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Code, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Code, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Code, new { htmlAttributes = new { #class = "checkbox center-block" } })
#Html.ValidationMessageFor(model => model.Code, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
</div>
<div class="panel-footer">
#Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
</div>
</div>
</div>
}
View
#model CreativeNamingConvention.Models.Domain.CreativeOps
#{
ViewBag.Model = Model;
ViewBag.Title = "Edit Creative Ops Field";
}
#Html.Partial("~/Views/Templates/editBody.cshtml", Model)
check null from your action method or razor view
dynamic keyword in C# 4.0 allows you to do a dynamic model binding
dynamic viewModel = new ExpandoObject();
viewModel.TestString = "This is a test string";
return View(viewModel); for more in refer the below link
examles
Dynamic model binding with examle
Based on that message, I assume that you can't use the "For" suffixed methods with dynamic operations.
Never used them, but you could try the generic form:
#Html.Label("Name", "Name Label", htmlAttributes: new { #class = "control-label col-md-2" })
The syntax says expression, so I assume it would support dot notation.
I figured out a simple approach if you are ok with basic css and nothing fancy.
You can use "EditForModel()" to display all of the properties in your model instead of "EditFor" each property. After this, for each property that you do not want to have displayed in your view, you can add "[ScaffoldColumn(false)]" in the model as shown below. Thanks for all the advice!!!
Partial
#model dynamic
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="container creative-containter-top">
<div class="row">
<div class="col-sm-offset-4 col-sm-4">
<div class="form-horizontal">
<div class="panel panel-primary">
<div class="panel-height pane panel-heading text-center">
<h3>#ViewBag.Title</h3>
</div>
<div class="panel-body">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-sm-offset-2">
<div class="form-group">
#Html.EditorForModel()
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
</div>
<div class="panel-footer">
#Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
</div>
</div>
</div>
}
Model
public partial class CreativeOps
{
public CreativeOps()
{
CreativeNames = new HashSet<CreativeNames>();
}
[ScaffoldColumn(false)]
public int Id { get; set; }
[Required]
public string Code { get; set; }
[Required]
public string Name { get; set; }
[Required]
public bool Disabled { get; set; }
public virtual ICollection<CreativeNames> CreativeNames { get; set; }
}
}

Create view for a child-master relationship

I have an entity called Entity, (lol).
public class Entidad
{
[Key]
public int Id { get; set; }
public string Nombre { get; set; }
public virtual ICollection<Propiedad> Propiedades { get; set; }
}
I also have an entity called Properties
public class Propiedad
{
[Key]
public int Id { get; set; }
public virtual Entidad Entidad { get; set; }
public string Codigo { get; set; }
public string Nombre { get; set; }
public string TipoDeDatos { get; set; }
}
My Create view with the automated scaffolding gets rendered like this
http://screencast.com/t/aNU4tEH8EA1
However, I should be able to select the Entity from a dropdown list.
this is the automatically generated view
#model Inspinia_MVC5.Areas.GlobalAdmin.Models.Propiedad
#{
ViewBag.Title = "Create";
Layout = "~/Areas/GlobalAdmin/Views/Shared/_LayoutGlobalAdmin.cshtml";
}
<div class="row wrapper border-bottom white-bg page-heading">
<div class="col-sm-4">
<h2>Create</h2>
<ol class="breadcrumb">
<li>
#Html.ActionLink("List", "Index")
</li>
<li class="active">
<strong>Create</strong>
</li>
</ol>
</div>
<div class="col-sm-8">
<div class="title-action">
#Html.ActionLink("Back to List", "Index", null, new { #class = "btn btn-primary"})
</div>
</div>
</div>
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Create Propiedad</h5>
</div>
<div class="ibox-content">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Codigo, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Codigo)
#Html.ValidationMessageFor(model => model.Codigo)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Nombre, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Nombre)
#Html.ValidationMessageFor(model => model.Nombre)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TipoDeDatos, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TipoDeDatos)
#Html.ValidationMessageFor(model => model.TipoDeDatos)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-primary" />
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn btn-white"})
</div>
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
Questions is how can I add the dropdown and make it fill the values from the entities?
You can't do that automatically.
You'll need to add a DropDownList to your View and add every entity you want to be selectable to this dropdown.
On the post, query for the entity, and then create Add the properties to it.
Also, check your controller, the default behavior for MVC is to create a child entity controller receiving the parent (in this case 'Entidad') id, make it receive only the model for semantics since you're not 'Entidad' specific in this case.

How to generate jQuery template in ASP.NET MVC?

I want to add input to form dynamically with jQuery templates.
My viewModel for rendering form is listed below
public class FormViewModel
{
public int Id { get; set; }
[Required]
[StringLength(25, ErrorMessage = "Max firstname length is 25 symbols.")]
[DisplayName("First name")]
public string FirstName { get; set; }
[Required]
[StringLength(25, ErrorMessage = "Max lastname length is 25 symbols.")]
[DisplayName("Last name")]
public string LastName { get; set; }
[Required]
[Email(ErrorMessage = "Provide correct email address, please.")]
[DisplayName("Email")]
public string Email { get; set; }
[Range(16, 150, ErrorMessage = "Age should be between 16 and 150.")]
[DisplayName("Age")]
public int? Age { get; set; }
public IList<DiscountCode> Discounts { get; set; }
}
This is my model which I use for inputs that will be created dynamically.
public class DiscountCode
{
[Required]
[DisplayName("Code name")]
[StringLength(10, ErrorMessage = "Max name length is 10 symbols.")]
public string Code { get; set; }
[Required]
[DisplayName("Code discount")]
[Integer(ErrorMessage = "The field Percent should be a positive non-decimal number")]
[Range(1,60, ErrorMessage = "The field Percent should be between 1 and 60.")]
public int Percent { get; set; }
}
I have this partial view for rendering DiscountCode inputs
#using DynamicForm.Models
#model FormViewModel
#if (Model != null && Model.Discounts != null)
{
for (int i = 0; i < Model.Discounts.Count; i++)
{
<div class="row">
<input type="hidden" name="Discounts.Index" value="#i" />
<div class="col-md-4 form-group">
<div class="input-group">
#Html.TextBoxFor(m => m.Discounts[i].Code, new { #class = "form-control " })
#Html.ValidationMessageFor(m => m.Discounts[i].Code, string.Empty, new { #class = "help-block" })
</div>
</div>
<div class="col-md-6 form-group">
<div class="input-group">
#Html.LabelFor(m => m.Discounts[i].Percent, new { #class = "control-label" })
#Html.TextBoxFor(m => m.Discounts[i].Percent, new { #class = "form-control " })
#Html.ValidationMessageFor(m => m.Discounts[i].Percent, string.Empty, new { #class = "help-block" })
</div>
</div>
<div class="col-md-2 form-group">
<div class="input-group">
<button type="button" class="btn btn-primary removeDiscountRow">Remove</button>
</div>
</div>
</div>
}
}
And for adding discount inputs I use this code snippet
var data = { index: lastIndex };
var html = $.templates("#discountRow").render(data);
$(html).appendTo($discountsContainer);
and this template
<script id="discountRow" type="text/x-jsrender">
<div class="row">
<input type="hidden" name="Discounts.Index" value="{{: index}}">
<div class="col-md-4 form-group">
<div class="input-group">
<label class="control-label" for="Discounts_{{: index}}__Code">Code name</label>
<input class="form-control " data-val="true" data-val-required="Code is required" data-val-length="Max name length is 10 symbols." data-val-length-max="10"
id="Discounts_{{: index}}__Code" name="Discounts[{{: index}}].Code" type="text" value="">
<span class="field-validation-valid help-block" data-valmsg-for="Discounts[{{: index}}].Code" data-valmsg-replace="true"></span>
</div>
</div>
<div class="col-md-6 form-group">
<div class="input-group">
<label class="control-label" for="Discounts_{{: index}}__Percent">Code discount</label>
<input class="form-control " data-val="true" data-val-required="Percent is required" data-val-number="The field Code discount must be a number."
data-val-range="The field Percent should be between 1 and 60." data-val-range-max="60" data-val-range-min="1"
data-val-regex="The field Percent should be a positive non-decimal number."
data-val-regex-pattern="^-?\d+$" data-val-required="The Code discount field is required."
id="Discounts_{{: index}}__Percent" name="Discounts[{{: index}}].Percent" type="text" value="0" aria-required="true" aria-invalid="false"
aria-describedby="Discounts_{{: index}}__Percent-error">
<span class="help-block field-validation-valid" data-valmsg-for="Discounts[{{: index}}].Percent" data-valmsg-replace="true"></span>
</div>
</div>
<div class="col-md-2 form-group">
<div class="input-group">
<button type="button" class="btn btn-primary removeDiscountRow">Remove</button>
</div>
</div>
</div>
</script>
As you can see I just copy output of razor and insert it in template. So if I change validation in model I'll change template each time. How to generate this template automatic with preserving all data attributes for client-side validation ?
You can generate templte code like you create your input code, but Model.Discounts must have at least one element. See code below. I add DiscountCode to discounts if its empty and change some html attributes to make template display as you want;)
if (Model.Discounts == null || Model.Discounts.Count <= 0)
{
Model.Discounts = new List<DiscountCode> { new DiscountCode() };
}
<script id="discountRow" type="text/x-jsrender">
<div class="row">
<input type="hidden" name="Discounts.Index" value="{{: index}}" />
<div class="col-md-4 form-group">
<div class="input-group">
#Html.LabelFor(m => m.Discounts[0].Percent, new { #class = "control-label", For = "Discounts[{{: index}}].Code" })
#Html.TextBoxFor(m => m.Discounts[0].Code, new { #class = "form-control ", Id = "Discounts_{{: index}}__Code", Name = "Discounts[{{: index}}].Code", Value="" } )
#Html.ValidationMessageFor(m => m.Discounts[0].Code, string.Empty, new { #class = "help-block", Data_Valmsg_For = "Discounts[{{: index}}].Code" })
</div>
</div>
<div class="col-md-6 form-group">
<div class="input-group">
#Html.LabelFor(m => m.Discounts[0].Percent, new { #class = "control-label", For = "Discounts[{{: index}}].Percent" })
#Html.TextBoxFor(m => m.Discounts[0].Percent, new { #class = "form-control ", Id = "Discounts_{{: index}}__Percent", Name = "Discounts[{{: index}}].Percent", Value = "" })
#Html.ValidationMessageFor(m => m.Discounts[0].Percent, string.Empty, new { #class = "help-block", Data_Valmsg_For = "Discounts[{{: index}}].Percent" })
</div>
</div>
<div class="col-md-2 form-group">
<div class="input-group">
<button type="button" class="btn btn-primary removeDiscountRow">Remove</button>
</div>
</div>
</div>
</script>

Categories

Resources