ModelState.IsValid always true - c#

Visual Studio 2015 Update 1.
MVC 5.2.3.
.NET 4.5.2
It's picking up the Display Name ok, but it's not honoring the Required attribute, it would seem. Thanks!!!
View:
#model Insure.Entities.Policy
#{ ViewBag.Title = "Policy"; }
<h2>Policy</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Create</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.EffDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EffDate)
#Html.ValidationMessageFor(model => model.EffDate)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ExpDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ExpDate)
#Html.ValidationMessageFor(model => model.ExpDate)
</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>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Model:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Insure.Entities
{
public class Policy
{
public int PolicyID { get; set; }
public Guid PolicyNumber { get; set; }
[Required(ErrorMessage = "Effective Date Required")]
[DataType(DataType.DateTime)]
[DisplayName("Effective Date")]
public DateTime EffDate { get; set; }
[Required(ErrorMessage = "Expiration Date Required")]
[DataType(DataType.DateTime)]
[DisplayName("Expiration Date")]
public DateTime ExpDate { get; set; }
}
}
Controller:
// POST: Policy/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FormCollection collection)
{
try
{
if (ModelState.IsValid)
{
// TODO: Add logic to insert to DB
return RedirectToAction("Index");
}
else
{
return View();
}
}
catch
{
return View();
}
}

public ActionResult Create(FormCollection collection)
should be
public ActionResult Create(Policy myPolicyModel)
Then validation will be executed on the model.

Related

File Upload Control Get Returned Null

Whenever i am clicking on submit after uploading file, it gets returned null, i have used all the necessary conditions required for upload file but still getting the issue, i have seen all the answers in stack overflow , i have used enctype and name of file upload is also same as what i am passing controller
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Officername,Designation,FileBeforeTour,FileAfterTour,FileBeforeTourName,FileAfterTourName")] FileDetails fileDetails)
{
if (ModelState.IsValid)
{
string uploadedfilename = Path.GetFileName(fileDetails.filebeforetourupload.FileName);
if (!string.IsNullOrEmpty(uploadedfilename))
{
db.FileUpload.Add(fileDetails);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(fileDetails);
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
namespace OnlineStationaryRegister.Models
{
public class FileDetails
{
[Key]
public int FileId { get; set; }
public string Officername { get; set; }
public string Designation { get; set; }
public string FileBeforeTour { get; set; }
public string FileAfterTour { get; set; }
public string FileBeforeTourName { get; set; }
public string FileAfterTourName { get; set; }
[NotMapped]
public HttpPostedFileBase filebeforetourupload { get; set; }
[NotMapped]
public HttpPostedFileBase fileaftertourupload { get; set; }
}
}
#model OnlineStationaryRegister.Models.FileDetails
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm("Create","File",FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>FileDetails</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Officername, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Officername, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Officername, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Designation, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Designation, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Designation, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.Label("File", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="filebeforetourupload" />
</div>
</div>
#*<div class="form-group">
#Html.LabelFor(model => model.FileAfterTour, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="fileaftertourupload" />
</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>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Change your controllers method as,This will fix your issue
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FileDetails fileDetails)
{
if (ModelState.IsValid)
{
string uploadedfilename =
Path.GetFileName(fileDetails.filebeforetourupload.FileName);
if (!string.IsNullOrEmpty(uploadedfilename))
{
db.FileUpload.Add(fileDetails);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(fileDetails);
}
Okay then this is what you should do. Instead of putting the HttpPostedFileBase field as part of the model, remove it from there and do this
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Officername,Designation,FileBeforeTour,FileAfterTour,FileBeforeTourName,FileAfterTourName")] FileDetails fileDetails, HttpPostedFileBase myFile)
{
}
then you can manipulate if from there. Sometimes the browser does not properly include files inside the model.

Capturing date time from the view into the database MVC

I created MVC application that has a text box posted to the database. When the text box is posted, I want to capture today's date from the view and store it into the table. How do I capture the date and time the view that posted and how do I pass this information into row Date within the database? Appreciate any help.
Controller
[HttpGet]
public ActionResult Pay(int accountNumber)
{
return View();
}
[HttpPost]
public ActionResult Pay(Payments payment )
{
if(ModelState.IsValid)
{
DB.Payment.Add(payment);
DB.SaveChanges();
var service = new Accounts(DB);
service.Updatepayee(payment.AccountNumber);
return RedirectToAction("Index", "Home");
}
return View();
}
Payments Class
public class Payments
public int Id { get; set; }
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public decimal Amount { get; set; }
[Required]
public int AccountNumber {get; set;}
[RegularExpression(#"(^$)|(^\d{2}/\d{2}/\d{4})|(^((\d{1})|(\d{2}))/((\d{1})|(\d{2}))/(\d{4})\s((\d{1})|(\d{2}))[:]{1}((\d{1})|(\d{2}))[:]{1}((\d{1})|(\d{2}))\s((AM)|(PM)))", ErrorMessage = "Invalid Date")]
public DateTime TransactionDate { get; set; }
//Navigation property to check the account
public virtual AccountNumber accountNumber { get; set; }
}
Pay View
#model Credits.View.Payments
#{
ViewBag.Title = "Pay"; }
<h2>Payments</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Transaction</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Amount, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Amount, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Amount, "", new { #class = "text-danger" })
</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> }
<div>
#Html.ActionLink("Back to List", "Index", "Home") </div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval") }
Couldn't you set it in the controller:
[HttpPost]
public ActionResult Pay(Payments payment )
{
if(ModelState.IsValid)
{
payment.TransactionDate = DateTime.Now.ToUniversalTime();
DB.Payment.Add(payment);
DB.SaveChanges();
[HttpPost]
public ActionResult Pay(Payments payment )
{
var d=DateTime.Now.ToUniversalTime();
if(ModelState.IsValid)
{
Payments p=new() Payments{
AccountNumber=p.AccountNumber,
Amount=payment.Amount,
TransactionDate=d
};
DB.Payment.Add(p);
DB.SaveChanges();

ASP.NET MVC-5 sever side validation not working

I have ASP.NET MVC application and I am failing to Server-side and client-side validation for partial page. In the start of my application there is login page which validating correctly. so if I press submit with no values in form, app don't show any error messages
model class
public class CreateFunctionNavigation_SP_Map
{
public CreateFunctionNavigation_SP_Map()
{
}
//Function Table
[StringLength(250)]
[Required(ErrorMessage = "Required Function Title")]
[Display(Name = "Function Title")]
public string FunctionName { get; set; }
[Required(ErrorMessage = "Required Function Hierarchy; i.e Where Function Exists In Hierarchy Tree \n Top-Level Start From 1 ")]
[Display(Name = "Function Hierarchy Level")]
public int FunctionHierarchy_Level { get; set; }
//Controller Table
[StringLength(250)]
[Required(ErrorMessage = "Required Controller Title")]
[Display(Name = "Controller Title")]
public string ControllerName { get; set; }
//Action Table
[StringLength(250)]
[Required(ErrorMessage = "Required Action Title")]
[Display(Name = "Action Title")]
public string ActionName { get; set; }
// Hierarchy Table
[Required(ErrorMessage = "Required Function Parent - Child Relation ID \n Put 0 In Case Given Function doesn't Have Any Parent Function ")]
[Display(Name = "Function Parent's FunctionID")]
public int Function_ParentsFunctionID { get; set; }
}
controller method
#region CreateNewFunctionNavigation
[HttpGet]
public ActionResult CreateNewFunctionNavigation()
{
return PartialView("CreateNewNavigation_Partial");
}
#endregion
[HttpPost]
public ActionResult CreateNewFunctionNavigation(CreateFunctionNavigation_SP_Map obj )
{
try
{
if(ModelState.IsValid)
{
_FN_Services_a2.CreateFunctionNavigation(obj);
}
}
catch (DataException ex)
{
ModelState.AddModelError("", "Unable To Create New Function Navigation" + ex);
}
return RedirectToAction("SystemCoreHome");
} //end
view
#model App.DAL.Model.CreateFunctionNavigation_SP_Map
<div class="_Form_Block">
#using (Html.BeginForm("CreateNewFunctionNavigation", "SystemCore", FormMethod.Post, new { id = "NewFunctionNavigationForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(#model => #model.FunctionName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.FunctionName)
#Html.ValidationMessageFor(#model => #model.FunctionName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.FunctionHierarchy_Level, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.FunctionHierarchy_Level)
#Html.ValidationMessageFor(#model => #model.FunctionHierarchy_Level)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.ControllerName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.ControllerName)
#Html.ValidationMessageFor(#model => #model.ControllerName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.ActionName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.ActionName)
#Html.ValidationMessageFor(#model => #model.ActionName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.Function_ParentsFunctionID, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.Function_ParentsFunctionID)
#Html.ValidationMessageFor(#model => #model.Function_ParentsFunctionID)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default _formButton" />
<input type="button" value="Cancel" class="btn btn-default _formButton" onclick="CancelPage();" />
</div>
</div>
}
</div> <!--End _Form_Block-->
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
instead of
return RedirectToAction("SystemCoreHome");
use
return PartialView("CreateNewNavigation_Partial", obj);
Ajax Form
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "TargetID" }))
{
...
}
<div class="_Form_Block" id="TargetID">
</div>
You need to handle this case.
Presently you are not doing anything in the event that the ModelState is invalid. Try the following:
public ActionResult CreateNewFunctionNavigation(CreateFunctionNavigation_SP_Map obj)
{
if (!ModelState.IsValid)
{
return View(obj);
}
// rest of method here
if(ModelState.IsValid)
{
_FN_Services_a2.CreateFunctionNavigation(obj);
}
else
{
return View();
}
Should do the trick.

NullReferenceException ASP.NET MVC 5

I have a web application with this controller:
public class ServiceRequestController : Controller
{
[Authorize(Roles = "Customer")]
public ActionResult Create()
{
return View();
}
[Authorize(Roles = "Customer")]
public ActionResult CreateNewUserAccount()
{
return View();
}
[Authorize(Roles = "Customer")]
[HttpPost]
public ActionResult CreateNewUserAccount(ServiceRequest serviceRequest)
{
if (ModelState.IsValid)
{
serviceRequest.Log.Id = User.Identity.GetUserId().ToString();
serviceRequest.Log.DateTimeLogged = System.DateTime.Now;
serviceRequest.LogID = db.Logs.Max(item => item.LogID);
serviceRequest.EstimatedResolveDate serviceRequest.CalculateEstimatedResolveDate();
db.ServiceRequests.Add(serviceRequest);
db.SaveChanges();
return RedirectToAction("AllServiceRequests", "Log");
}
return View(serviceRequest);
}
The serviceRequest.Log.Id = User.Identity.GetUserId().ToString(); (And any preceding line if this is commented out) throws a null reference exception. I presume the serviceRequest is somehow null?
The ActionLink which requests the CreateNewUserAccount() page is:
#Html.ActionLink("New User Account", "CreateNewUserAccount", "ServiceRequest")
I'm not sure how to resolve this exception?
The model is:
public partial class ServiceRequest
{
public int ServiceRequestID { get; set; }
public Nullable<int> LogID { get; set; }
public string RequestType { get; set; }
[DisplayName("Additional Information")]
[Required]
[StringLength(200)]
public string AdditionalInformation { get; set; }
public DateTime EstimatedResolveDate { get; set; }
[Required]
[DisplayName("Delivery Date")]
public DateTime DeliveryDate { get; set; }
public virtual Log Log { get; set; }
public DateTime CalculateEstimatedResolveDate()
{
return System.DateTime.Now.AddDays(3);
}
}
View code:
#model OfficiumWebApp.Models.ServiceRequest
#{
ViewBag.Title = "New User Account";
}
#using(Html.BeginForm("CreateNewUserAccount", "ServiceRequest", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.RequestType, new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.TextBoxFor(model => model.RequestType, new { #Value = ViewBag.Title, #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.RequestType)
</div>
</div>
</div>
<div class="form-group">
#Html.Label("Name of Account Holder", new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.TextBox("AccountName")
#Html.ValidationMessageFor(model => model.RequestType)
</div>
</div>
</div>
<div class="form-group">
#Html.Label("Department", new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.TextBox("Department")
#Html.ValidationMessageFor(model => model.RequestType)
</div>
</div>
</div>
<div class="form-group">
#Html.Label("Location", new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.TextBox("Location", null, new { id = "Location" }))
#Html.ValidationMessageFor(model => model.RequestType)
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AdditionalInformation, new { #class = "control-label col-md-2" })
<div class="tags">
<div class="col-md-10">
#Html.TextAreaFor(model => model.AdditionalInformation)
#Html.ValidationMessageFor(model => model.AdditionalInformation)
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DeliveryDate, new { #id = "VisitDateLabel", #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.JQueryUI().DatepickerFor(model => model.DeliveryDate).Inline(false)
#Html.ValidationMessageFor(model => model.DeliveryDate)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-floppy-save"></span></button>
</div>
</div>
</div>
}
You need to return the view i.e.
[Authorize(Roles = "Customer")]
public ActionResult CreateNewUserAccount()
{
var model = new ServiceRequest();
model.Log = new Log();
return View(model);
}
In your view you need to add a model reference too at the top i.e.
#model ServiceRequest
You could also initialise the Log object in your model as follows:
public class ServiceRequest
{
public ServiceRequest()
{
Log = new Log();
}
....
}
An action link will not post your model back, you need to include it within a form and include all the model values that you want to be updated on the client i.e.
#using (Html.BeginForm("CreateNewUserAccount", "ServiceRequest", FormMethod.Post)){
#Html.EditorFor(m => m.AdditionalInformation)
...
<input type="submit" value="submit" />
Update
Taken from the below comments, this was resolved by creating a new log on post i.e.
var log = new Log {
Id = User.Identity.GetUserId().ToString(),
DateTimeLogged = System.DateTime.Now,
LogID = db.Logs.Max(item => item.LogID) };
serviceRequest.Log = log;

Error with generated view

What is wrong with the following code? It was generated by teh add view wizard. And when I navigate to the controller I get the following error: String was not recognised as a valid Boolean and the following line is highlighted: #using (Html.BeginForm())
Here is the view:
#model Radio_Management_Interface.DomainModel.Entities.Network
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout_main.cshtml";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Network</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.name)
#Html.ValidationMessageFor(model => model.name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.startCode, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.startCode)
#Html.ValidationMessageFor(model => model.startCode)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.frequency, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.frequency)
#Html.ValidationMessageFor(model => model.frequency)
</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>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}`
Controller:
//
// GET: /Networks/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Network network = db.Networks.Find(id);
if (network == null)
{
return HttpNotFound();
}
return View(network);
}
Domain Model:
public class Network
{
public int networkID { get; set; }
public string name { get; set; }
public int startCode { get; set; }
public decimal frequency { get; set; }
public virtual List<Block> blocks { get; set; }
}
Your id is a nullable type, replace it with this line instead:
Network network = db.Networks.Find(id.Value);
And this:
if (id == null)
Can be changed to this:
if (!id.HasValue)
The problem will be with the following line:
Network network = db.Networks.Find(id);
The id is actually a nullable type that is passed to your Find method when it is expecting the value.
With nullable types you can read the underlying value with the Value property i.e.
id.Value

Categories