How to get multiple answers from radio buttons when clicking submit ASP.NET CORE MVC - asp.net-core-mvc

This is a quiz with around 40 questions and each question with multiple answers.
Everything looks fine until I try to catch the answers from the view to the controller because everything returns 0 or null, Please help!
This is what I have
The Database looks like this:
Model Evaluacion:
namespace ENCB_Placement_Test_Official.Models
{
public class Evaluacion
{
public int ExamenId { get; set; }
public int RegistroId { get; set; }
public int ReactivoId { get; set; }
public string RespuestaAlumno { get; set; }
public string Pregunta { get; set; }
public string Respuesta1 { get; set; }
public string Respuesta2 { get; set; }
public string Respuesta3 { get; set; }
public string Respuesta4 { get; set; }
}
}
Services folder with a class called RepositorioExaluaciones
namespace ENCB_Placement_Test_Official.Servicios
{
public interface IRepositorioEvaluaciones
{
Task EnviarRespuesta(Evaluacion evaluacion);
Task<IEnumerable<Evaluacion>> ObtenerEvaluaciones();
}
public class RepositorioEvaluaciones: IRepositorioEvaluaciones
{
private readonly string connectionString;
public RepositorioEvaluaciones(IConfiguration configuration)
{
connectionString = configuration.GetConnectionString("DefaultConnection");
}
public async Task<IEnumerable<Evaluacion>> ObtenerEvaluaciones()
{
using var connection = new SqlConnection(connectionString);
return await connection.QueryAsync<Evaluacion>(#"SELECT Examenes.Id AS ExamenId,
RegistroId,
ReactivoId,
RespuestaAlumno,
Pregunta,
Respuesta1,
Respuesta2,
Respuesta3,
Respuesta4
FROM Examenes
INNER JOIN Reactivos
ON Examenes.ReactivoId = Reactivos.Id
WHERE Examenes.RegistroId = 1");
}
public async Task EnviarRespuesta(Evaluacion evaluacion)
{
using var connection = new SqlConnection(connectionString);
connection.Execute(#"UPDATE Examenes
SET RespuestaAlumno = #RespuestaAlumno
WHERE RegistroId = #RegistroId", evaluacion);
}
}
}
Controller Evaluaciones
namespace ENCB_Placement_Test_Official.Controllers
{
public class EvaluacionesController:Controller
{
private readonly IRepositorioEvaluaciones repositorioEvaluaciones;
public EvaluacionesController(IRepositorioEvaluaciones repositorioEvaluaciones)
{
this.repositorioEvaluaciones = repositorioEvaluaciones;
}
public async Task<IActionResult> Evaluar()
{
if (!ModelState.IsValid)
{
return View();
}
var obtenerExamen = await repositorioEvaluaciones.ObtenerEvaluaciones();
return View(obtenerExamen);
}
[HttpPost]
public async Task<IActionResult> Evaluar(Evaluacion evaluacion)
{
if (!ModelState.IsValid)
{
return View(evaluacion);
}
await repositorioEvaluaciones.EnviarRespuesta(evaluacion);
return View();
}
}
}
View Evaluar, this is where I think I have the problem because when I debug the app and click the submit button I just get nulls and zeros
#model IEnumerable<Evaluacion>
#{
ViewData["Title"] = "Start Assesment";
var contador = 1;
}
<h1>Start Assesment</h1>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<form asp-action="Evaluar" method="post">
#foreach (var reactivo in Model)
{
<div class="mb-3">
<label class="form-label">#contador . #reactivo.Pregunta</label>
<div class="form-check">
<input class="form-check-input" type="radio" id="#reactivo.ExamenId" name="#reactivo.ExamenId" value="Respuesta1" checked />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta1</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="#reactivo.ExamenId" name="#reactivo.ExamenId" value="Respuesta2" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta2</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="#reactivo.ExamenId" name="#reactivo.ExamenId" value="Respuesta3" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta3</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="#reactivo.ExamenId" name="#reactivo.ExamenId" value="Respuesta4" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta4</label>
</div>
</div>
contador++;
}
<button type="submit" class="btn btn-primary">Send Response</button>
</form>
It is supposed to return an answer like "Respuesta1" and it should be stored in the Model.RespuestaAlumno and I just don't have any idea on how can I do it. please help.

In your Model Design, You need a property to receive the value of the selected answer(maybe you already have that property in your model,I don't understand spanish), So I create that property:
public class Evaluacion
{
public int ExamenId { get; set; }
public int RegistroId { get; set; }
public int ReactivoId { get; set; }
public string RespuestaAlumno { get; set; }
public string Pregunta { get; set; }
public string Respuesta1 { get; set; }
public string Respuesta2 { get; set; }
public string Respuesta3 { get; set; }
public string Respuesta4 { get; set; }
public string Answer { get; set; }
}
Then in your View, name uses property names for binding and it asked to start at index 0. I write a simple demo here, you can refer to it:
#model IEnumerable<Evaluacion>
#{
ViewData["Title"] = "Start Assesment";
var contador = 1;
}
<h1>Start Assesment</h1>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<form asp-action="Evaluar" method="post">
#foreach (var reactivo in Model)
{
int i = contador - 1;
<div class="mb-3">
<label class="form-label">#contador . #reactivo.Pregunta</label>
<div class="form-check ">
<input class="form-check-input" type="radio" name="[#i].Answer" value="#reactivo.Respuesta1" checked />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta1</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="[#i].Answer" value="#reactivo.Respuesta2" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta2</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="[#i].Answer" value="#reactivo.Respuesta3" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta3</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="[#i].Answer" value="#reactivo.Respuesta4" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta4</label>
</div>
</div>
contador++;
}
<button type="submit" class="btn btn-primary">Send Response</button>
</form>
Finally, The type of the model passed into the controller from the page is IEnumerable, You can't just use Evaluacion to receive, You need to change like this:
[HttpPost]
public async Task<IActionResult> Evaluar(List<Evaluacion> evaluacion)
{
//.......
return View(evaluacion);
}
Demo:
You can see the project can receive the answer successfully.

Related

Display validation error message - compare one input against another

Entered Max value must be greater than Min. Right now my code displays error message when Max is same as Min (using compare). Is there validator that can be used to compare one input against another?
MyData.cs:
public class MyData
{
[Required]
public double Min { get; set; }
[Compare("Min", ErrorMessage = "checks for matching min value")]
public double Max { get; set; }
}
Form.razor:
<div class="modal-body">
<EditForm EditContext="#context">
<DataAnnotationsValidator />
<label class="form-label" for="Min">Min</label>
<input class="form-control" #bind=model.Min type="text">
<label class="form-label" for="Max">Max</label>
<input class="form-control" #bind=model.Max type="text">
<ValidationMessage For="#(() => model.Max)" />
</EditForm>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" #onclick="() => Done()">Apply</button>
</div>
#code {
private MyData model = new MyData();
private EditContext context;
protected override void OnInitialized()
{
model = (MyData)(modalDialog?.ModalRequest.InData ?? new MyData());
context = new EditContext(model);
}
private void Done()
{
if (#model.Max < #model.Min)
{
context.Validate(); #*this displays error message*#
}
else
{
modalDialog?.Close(ModalResult.OK(model));
}
}
To validate for greater than or less than against another property instead of a value using Data Annotations you require to create a custom validation attribute as shown below:
GreaterThan attribute
// Custom attribute for validating greater than other property
public class GreaterThan : ValidationAttribute
{
private readonly string _comparisonProperty;
public GreaterThan(string comparisonProperty)
{
_comparisonProperty = comparisonProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ErrorMessage = ErrorMessageString;
var currentValue = (double)value; // cast to double same as property type
var property = validationContext.ObjectType.GetProperty(_comparisonProperty);
if (property == null)
throw new ArgumentException("Property with this name not found");
var comparisonValue = (double)property.GetValue(validationContext.ObjectInstance); // cast to property type
// comparison condition
if (currentValue < comparisonValue)
return new ValidationResult(ErrorMessage);
return ValidationResult.Success;
}
}
LessThan attribute
You can use the same code above to create for LessThan attribute by changing the name and comparison condition to currentValue > comparisonValue.
Below is an example on how to use Data Annotations to validate your model and display validation errors in the form. It includes GreaterThan custom validation attribute together with other common validation attribute.
Demo
Class:
public class MyData
{
[Required]
[MaxLength(40, ErrorMessage = "Name should be less than 40 characters")]
[MinLength(4, ErrorMessage ="Name should be more than 4 characters")]
public string Name { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime? BirthDate { get; set; }
[Required]
public double Min { get; set; }
[GreaterThan("Min", ErrorMessage = "Max must be greater than Min")]
public double Max { get; set; }
[Required(ErrorMessage = "Password is required.")]
public string Password { get; set; }
[Required(ErrorMessage = "Confirmation Password is required.")]
[Compare("Password", ErrorMessage = "Password and Confirmation Password must match.")]
public string ConfirmPassword { get; set; }
}
Razor:
Note: you can upgrade the styling for your form fields and validation message to your liking.
#page "/"
#using BlazorApp1.Models
<EditForm Model="#myData" OnValidSubmit="#HandleValidSubmit">
<DataAnnotationsValidator/>
<ValidationSummary/>
<p>
<label for="Name">Name: </label>
<InputText id="Name" #bind-Value="myData.Name"/>
<ValidationMessage For="() => myData.Name"/>
</p>
<p>
<label for="Min">Min: </label>
<InputNumber id="Min" #bind-Value="myData.Min"/>
<ValidationMessage For="() => myData.Min"/>
</p>
<p>
<label for="Max">Max: </label>
<InputNumber id="Max" #bind-Value="myData.Max"/>
<ValidationMessage For="() => myData.Max"/>
</p>
<p>
<label for="BirthDate">BirthDate: </label>
<InputDate id="BirthDate" #bind-Value="myData.BirthDate"/>
<ValidationMessage For="() => myData.BirthDate"/>
</p>
<p>
<label for="Password">Password: </label>
<InputText id="Password" #bind-Value="myData.Password"
type="password"/>
<ValidationMessage For="() => myData.Password"/>
</p>
<p>
<label for="ConfirmPassword">ConfirmPassword: </label>
<InputText id="ConfirmPassword" #bind-Value="myData.ConfirmPassword"
type="password"/>
<ValidationMessage For="() => myData.ConfirmPassword"/>
</p>
<button type="submit">Submit</button>
</EditForm>
#code {
private readonly MyData myData = new();
private void HandleValidSubmit()
{
// Save the data
}
}
Output:

Model binding is not properly working in input parameter controller in .Net Core

I am trying to Alldata transfer a from Model to ViewModel.But the input parameter can't input several data. for that this data I can not use my session to create a cart system. Here is my code.`enter code here.
public class ProductVm: Spray
{ }
public class Spray
{
public int Id { get; set; }
[Required]
public String Name { get; set; }
[Required]
public decimal Price { get; set; }
public String Image { get; set; }
public String Image1 { get; set; }
[Required]
public String ProductColor { get; set; }
public DateTime Date { get; set; }
[Required]
public int Quantity { get; set; }
[Required]
public int Size { get; set; }
[Required]
public String Description { get; set; }
[Display(Name = "Product Type")]
public int ProductTypeId { get; set; }
[ForeignKey("ProductTypeId")]
public ProductTypes ProductTypes { get; set; }
}
[HttpGet]
public ActionResult Details(int? id)
{
if (id == null)
{
return NotFound();
}
var hi = _db.Spray.Include(c => c.ProductTypes).FirstOrDefault(c => c.Id == id);
ProductVm product = new ProductVm
{
Name = hi.Name,
Id = hi.Id,
Image = hi.Image,
Quantity = hi.Quantity,
Price = hi.Price,
};
if (product == null)
{
return NotFound();
}
return View(product);
}
[HttpPost]
[ActionName("Details")]
public async Task <IActionResult> ProductDetails(ProductVm pb)
{
List<Spray> sprays = new List<Spray>();
//if (id == null)
//{
// return NotFound();
//}
//var yes = _db.Spray.Include(c => c.ProductTypes).FirstOrDefault(c => c.Id == id);
ProductVm product = new ProductVm()
{
Name = pb.Name,
Id=pb.Id,
Image=pb.Image,
Quantity=pb.Quantity,
Price=pb.Price,
};
if (product == null)
{
return NotFound();
}
sprays = HttpContext.Session.Get<List<Spray>>("sprays");
if (sprays == null)
{
sprays = new List<Spray>();
}
sprays.Add(product);
HttpContext.Session.Set("sprays", sprays);
return RedirectToAction(nameof(Index));
}
#model ProductVm
#{
ViewData["Title"] = "Details.Cshtml";
}
#*#using OnlineShop.Utility
#using Microsoft.AspNetCore.Http
#inject IHttpContextAccessor HttpContextAccessor
#{
List<Laptop> laptops = HttpContextAccessor.HttpContext.Session.Get<List<Laptop>>("laptops");
Laptop laptop = null;
if (laptops != null)
{
laptop = laptops.FirstOrDefault(c => c.Id == Model.Id);
}
}
<br />*#
<h2 class="text-info"> Product Details</h2>
</br></br>
#*<form method="post" asp-action="" enctype="multipart/form-data">*#
<form method="post" asp-action="" enctype="multipart/form-data">
<div class="row">
<div class="col-1">
<img src="~/#Model.Image" style="width:100%" onclick="myFunction(this);">
</br></br>
<img src="~/#Model.Image1" style="width:100%" onclick="myFunction(this);">
</div>
<div class="col-4 container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
<img id="expandedImg" style="width:100%">
<div id="imgtext"></div>
</div>
<div class="col-4">
<h2>#Model.Name</h2>
<p><b>#Model.Description</b></p>
<h4>#Model.Price $</h4>
<small class="text-danger">Clearence</small>
</br>
<hr>
<h4>Size:#Model.Size</h4>
<h6>Product Color:#Model.ProductColor</h6>
</br></br></br></br>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<div class="col-sm-12 col-xs-12 spinner-block">
<div class="number-spinner">
<div class="input-group number-spinner">
<b class="mr-4"> <label asp-for="#Model.Quantity"></label></b></br>
<span class="input-group-btn">
<button type="button" class="btn btn-default btn-number btncartsniper" data-type="minus" data-dir="dwn"><span class="fa fa-minus fa-sm"></span></button>
</span>
<input asp-for="#Model.Quantity" class="form-control input-number Snippper_qty" value="0" type="number">
<span class="input-group-btn">
<button type="button" class="btn btn-default btn-number btncartsniper" data-type="plus" data-dir="up"><span class="fa fa-plus fa-sm"></span></button>
</span>
</div>
</div>
</div>
#*#if (Model.Quantity > 0)
{
<h1>This Product Is InStock</h1>
}
else
{
<h1>Not InStock</h1>
}*#
</br>
<input type="submit" class="btn btn-dark form-control" value="Add To Cart" />
</div>
</div>
below picture, I am successful to transfer data to ViewModel but next failed to data-bind.
enter image description here
enter image description here
I am a beginner. Please, anyone, help me
can't scope this image under input tag
As #Ben mentioned, you can use hidden input to store the value that img needs to pass like:
<img src="~/#Model.Image" style="width:100%" onclick="myFunction(this);">
<input type="hidden" asp-for="Image">
Another way is to use ajax to pass any model you want:
<img src="~/#Model.Image" style="width:100%" onclick="myFunction(this);" data="#Model.Image">
<script>
var productVm =
{
//other fields
"Image": $("#Image").attr("data"),
}
$.ajax({
url: '/Home/Details',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(productVm)
});
</script>
Your Quantity property is passing back through pb because it has an <input> property.
You need to make sure anything you want to pass back to POST action has an input tag associated with it. If you don't want the user to see it, type="hidden" is a good candidate. However, if those fields are not editable by a user you could simply just grab them in the POST action too if you need them.

Listbox for MVC 6 EF 7 Property not Populating

I've been trying for a while now to get a list box to populate and I can't seem to figure it out. I've studied entity framework 7 documentation pretty extensively but I'm still new to it. There aren't a lot of tutorials out there for MVC6/EF7 yet so its been hard to know what the best practice is for associating one entity class with an instance of another. Please excuse the length of the question, I'm just trying to be thorough.
I'm using entity framework 7, asp.net 5 and MVC 6.
Steps To Reproduce Issue
Create a new ASP.Net Web Application → Name of project: ListBox.Web → Name of solution ListBox
Choose APS.NET 5 Templates → Web Application
Create two classes in the Models folder
Parent.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ListBox.Web.Models
{
public class Parent
{
public int ParentId { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Child> Children { get; set; }
}
}
Child.cs
using System.ComponentModel.DataAnnotations;
namespace ListBox.Web.Models
{
public class Child
{
public int ChildId { get; set; }
[Required]
public string Name { get; set; }
public int ParentId { get; set; }
public Parent Parent { get; set; }
}
}
Create controllers and views for each of the data classes using scaffolding
Add links to the controllers in _Layout.cshtml
<ul class="nav navbar-nav">
<li><a asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-controller="Parents" asp-action="Index">Parents</a></li>
<li><a asp-controller="Children" asp-action="Index">Children</a></li>
<li><a asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
Create the database
ListBox\src\ListBox.Web>dns ef migrations add Initial
ListBox\src\ListBox.Web>dnx ef database update
Run the web application
Add a couple parents.
Attempt to add a child.
A drop box is shown for parents but there are no items in the drop box to select
The HTML for the list box is: <select class="form-control" data-val="true" data-val-required="The ParentId field is required." id="ParentId" name="ParentId"></select>
Controller Source Code
using System.Linq;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Data.Entity;
using ListBox.Web.Models;
namespace ListBox.Web.Controllers
{
public class ChildrenController : Controller
{
private ApplicationDbContext _context;
public ChildrenController(ApplicationDbContext context)
{
_context = context;
}
// GET: Children
public IActionResult Index()
{
var applicationDbContext = _context.Child.Include(c => c.Parent);
return View(applicationDbContext.ToList());
}
// GET: Children/Details/5
public IActionResult Details(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
return View(child);
}
// GET: Children/Create
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent");
return View();
}
// POST: Children/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Child child)
{
if (ModelState.IsValid)
{
_context.Child.Add(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// GET: Children/Edit/5
public IActionResult Edit(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// POST: Children/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Child child)
{
if (ModelState.IsValid)
{
_context.Update(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// GET: Children/Delete/5
[ActionName("Delete")]
public IActionResult Delete(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
return View(child);
}
// POST: Children/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public IActionResult DeleteConfirmed(int id)
{
Child child = _context.Child.Single(m => m.ChildId == id);
_context.Child.Remove(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
}
}
Child Create.cshtml
#model ListBox.Web.Models.Child
#{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<form asp-action="Create">
<div class="form-horizontal">
<h4>Child</h4>
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="ParentId" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="ParentId" class ="form-control"></select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}
Change Create() method in ChildrenController, change
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent");
return View();
}
to
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Name");
return View();
}
In Create.cshtml, change
<select asp-for="ParentId" class="form-control"></select>
to
#Html.DropDownList("ParentId", null, htmlAttributes: new { #class = "form-control" })
The generated code is incorrect, it is a bug https://github.com/aspnet/Scaffolding/issues/149
One solution using "tag helpers" is:
Controller
...
ViewData["Parents"] = new SelectList(_context.Set<Parent>(), "ParentId", "Name", child.ParentId);
...
View
#{
var parents = (IEnumerable<SelectListItem>)ViewData["Parents"];
}
...
<select asp-for="ParentId" asp-items="parents" class ="form-control">
<option disabled selected>--- SELECT ---</option>
</select>
...
Here's how to do it when there is only one type of object which is nested within another object of the same type.
Object:
public class Fleet
{
public int Id { get; set; }
public Fleet ParentFleet { get; set; }
public int? ParentFleetId { get; set; }
public string Name { get; set; }
[InverseProperty("ParentFleet")]
public virtual List<Fleet> Children { get; set; }
public List<UserFleet> UserFleets { get; set; }
}
Controller:
ViewData["ParentFleetId"] = new SelectList(_context.Set<Fleet>(), "Id", "Name");
return View();
View:
<form asp-action="Create">
<div class="form-horizontal">
<h4>Fleet</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="ParentFleet" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="ParentFleetId" asp-items="ViewBag.ParentFleetId" class="form-control">
<option value=""></option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>

Pass Json data object from view containing partial view in MVC4

I am creating an MVC4 Form for person.
I have these Partial Views containing Information about Contact Info and Postal Address.
ContactInfo.cshtml
#model Demo.Models.ContactInfo
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<link rel="stylesheet" href="~/Content/plugins/validationengine/css/validationEngine.jquery.css" />
<h2>ContactInfo</h2>
<div class="form-group">
<label class="control-label col-lg-4">PhoneNumber</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.PhoneNumber)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">CellNumber</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.CellNumber)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Email</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.Email)
</div>
</div>
PostalAddress.cshtml
#model Demo.Models.PostalAddress
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<link rel="stylesheet" href="~/Content/plugins/validationengine/css/validationEngine.jquery.css" />
<h2>PostalAddress</h2>
<div class="form-group">
<label class="control-label col-lg-4">CountryID</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.CountryID)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">CityID</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.CityID)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">ProvinceID</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.ProvinceID)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">ZipCode</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.ZipCode)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">StreetAddress</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.StreetAddress)
</div>
</div>
Here are the Model classes for Person,Postal Address and Contact Info.
ContactInfo.cs
using System;
using System.Collections.Generic;
namespace Demo.Models
{
public partial class ContactInfo
{
public ContactInfo()
{
this.Branches = new List<Branch>();
this.People = new List<Person>();
}
public long ID { get; set; }
public Nullable<int> PhoneNumber { get; set; }
public Nullable<int> CellNumber { get; set; }
public string Email { get; set; }
public virtual ICollection<Branch> Branches { get; set; }
public virtual ICollection<Person> People { get; set; }
}
}
Here is the Person.cs
using System;
using System.Collections.Generic;
namespace Demo.Models
{
public partial class Person
{
public Person()
{
this.Branches = new List<Branch>();
this.Documents = new List<Document>();
this.Faculties = new List<Faculty>();
this.Institutes = new List<Institute>();
this.Parents = new List<Parent>();
this.Students = new List<Student>();
this.StudentParents = new List<StudentParent>();
this.StudentParents1 = new List<StudentParent>();
}
public long ID { get; set; }
public string Name { get; set; }
public Nullable<bool> Gender { get; set; }
public Nullable<System.DateTime> DOB { get; set; }
public string Photo { get; set; }
public Nullable<long> ContactID { get; set; }
public Nullable<byte> PersonTypeID { get; set; }
public Nullable<long> PostalAddressID { get; set; }
public Nullable<byte> ReligionID { get; set; }
public virtual ICollection<Branch> Branches { get; set; }
public virtual ContactInfo ContactInfo { get; set; }
public virtual ICollection<Document> Documents { get; set; }
public virtual ICollection<Faculty> Faculties { get; set; }
public virtual ICollection<Institute> Institutes { get; set; }
public virtual ICollection<Parent> Parents { get; set; }
public virtual PersonType PersonType { get; set; }
public virtual PostalAddress PostalAddress { get; set; }
public virtual Religion Religion { get; set; }
public virtual ICollection<Student> Students { get; set; }
public virtual ICollection<StudentParent> StudentParents { get; set; }
public virtual ICollection<StudentParent> StudentParents1 { get; set; }
}
}
PostalAddress.cs
using System;
using System.Collections.Generic;
namespace Demo.Models
{
public partial class PostalAddress
{
public PostalAddress()
{
this.Branches = new List<Branch>();
this.Papers = new List<Paper>();
this.People = new List<Person>();
}
public long ID { get; set; }
public Nullable<byte> CountryID { get; set; }
public Nullable<int> CityID { get; set; }
public Nullable<int> ProvinceID { get; set; }
public string ZipCode { get; set; }
public string StreetAddress { get; set; }
public virtual ICollection<Branch> Branches { get; set; }
public virtual city city { get; set; }
public virtual country country { get; set; }
public virtual ICollection<Paper> Papers { get; set; }
public virtual ICollection<Person> People { get; set; }
public virtual province province { get; set; }
}
}
Here is the Main Person.cshtml
I am rendering the upper partial views in it and sending the json object data back.
#model Demo.Models.Person
#{
ViewBag.Title = "Person";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<legend>Person</legend>
<div class="form-group">
<label class="control-label col-lg-4">Name</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.Name)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Gender</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.Gender)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">DOB</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.DOB)
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Photo</label>
<div class="col-lg-4">
#Html.EditorFor(model => model.Photo)
</div>
</div>
#Html.Partial("ContactInfo", new Demo.Models.ContactInfo())
<div class="form-group">
<label class="control-label col-lg-4">PersonTypeID</label>
<div class="col-lg-4">
#Html.DropDownList("PersonTypeID", String.Empty)
</div>
</div>
#Html.Partial("PostalAddress", new Demo.Models.PostalAddress())
<div class="form-group">
<label class="control-label col-lg-4">ReligionID</label>
<div class="col-lg-4">
#Html.DropDownList("ReligionID", String.Empty)
</div>
</div>
<p>
<input id="submit" class="submit" type="submit" value="Create" />
</p>
}
<script>
$('#submit').click(function (e) {
e.preventDefault();
//alert('hello');
var person = {
Name: $('#Name').val(),
Gender: $('#Gender').val(),
DOB: $('#DOB').val(),
Photo: $('#Photo').val(),
PersonTypeID: $('PersonTypeID').val(),
ContactInfo: {
PhoneNumber: $('#PhoneNumber').val(),
CellNumber: $('#CellNumber').val(),
Email: $('#Email').val()
},
PostalAddress: {
CountryID: $('#CountryID').val(),
CityID: $('#CityID').val(),
ProvinceID: $('#ProvinceID').val(),
ZipCode: $('#ZipCode').val(),
StreetAddress: $('#StreetAddress').val(),
},
};
var data = { jsonperson: person };
//console.log(data);
$.ajax({
url: '/Person/Create',
type: "post",
data: JSON.stringify(data),
success: function () {
$('#message').html('person added').fadeIn();
},
error: function () {
$('#message').html('person added').fadeIn();
}
});
But when i send the data from form to controller The data containing postal address and Contact info is Null.
Here is the Person Controller
[HttpPost]
public JsonResult Create(Person jsonperson)
{
if (ModelState.IsValid)
{
db.People.Add(jsonperson);
db.SaveChanges();
// return RedirectToAction("Index");
}
ViewBag.ContactID = new SelectList(db.ContactInfoes, "ID", "Email", jsonperson.ContactID);
ViewBag.PersonTypeID = new SelectList(db.PersonTypes, "ID", "Name", jsonperson.PersonTypeID);
ViewBag.PostalAddressID = new SelectList(db.PostalAddresses, "ID", "ZipCode", jsonperson.PostalAddressID);
ViewBag.ReligionID = new SelectList(db.Religions, "ID", "Name", jsonperson.ReligionID);
// return View(jsonperson);
JsonResult jr = new JsonResult();
jr.Data = true;
return jr;
}
Data is coming to the controller but Contact Info details and Postal Address is null. It is driving me crazy .
Thanks in advance.
the serialized JSON data that is being passed to your controller after you submit the form, does not have any property such as ContactId or PersonTypeID etc
your controller will receive PhoneNumber, CellNumber, Email, CountryID, CityID, ProvinceID, ZipCode, StreetAddress
therefore your model Person should have the above properties as it is named in your partial view models so they can be read accordingly into your Person model.

How to upload an image to sql server in ASP.NET MVC3 RAZOR

In my ASP.NET MVC3 RAZOR project i have to implement image upload.I have tried different Tutorials and none working fine for me.I have a model ,controller and a view file.
There is as search action ,from the search action the customer List will be loaded with an option to upload Files.
here my question is how to upload an image to sql server using ASP.Net MVC3 Razor
Model Code
namespace Elixir.Models
{
[Table("tbl_ElixiCustPro")]
public class ElixiCustPro
{
[Key]
public int ImageId { get; set; }
public int CusId { get; set; }
public string CustomerName { get; set; }
public string ImageUrl { get; set; }
public byte[] Image { get; set; }
}
}
Controller
[HttpGet]
public ActionResult UploadPhoto()
{
return View();
}
[HttpPost]
public ActionResult UploadPhoto(ElixiCustPro elixi, HttpPostedFileBase uploadfile, int CusId,string Name)
{
if (uploadfile != null && uploadfile.ContentLength > 0)
{
elixi.Image = new byte[uploadfile.ContentLength];
uploadfile.InputStream.Read(elixi.Image, 0, uploadfile.ContentLength);
}
try
{
if (ModelState.IsValid)
{
ecp.Image = new byte[uploadfile.ContentLength];
ecp.ImageUrl = "";
ecp.CustomerName = Name;
ecp.CusId = CusId;
ment.ElixiProData.Add(ecp);
ment.SaveChanges();
return RedirectToAction("Index");
}
}
catch
{
return View();
}
return View();
}
View Code
<legend>File Management</legend>
#using (Html.BeginForm("UploadPhoto", "Home",FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<label class="col-lg-2 control-label">
Customer ID</label>
<div class="col-lg-10">#Html.TextBoxFor(model => model.CusId, new { #class = "form-control" })</div>
<label class="col-lg-2 control-label">
Customer Name</label>
<div class="col-lg-10">#Html.TextBoxFor(model => model.Name, new { #class = "form-control" })</div>
</div>
<input type="hidden" id="id" />
<div class="col-md-6">
<div class="form-group">
<label class="col-lg-2 control-label">
DMIT Image</label>
<div class="col-lg-10">
<input type="file" id="file" name="file">
<input type="submit" class="btn btn-success" value="Upload" />
</div>
</div>
</div>
}

Resources