MVC Validation Not Working In Web Forms Project - asp.net-mvc

I have the following code in my aspx view page:
<% using (Html.BeginForm())
{
%>
<div>
CustomerCode:
<%= Html.TextBoxFor(x=> x.CustomerCode) %>
<%= Html.ValidationMessageFor(x => x.CustomerCode)%>
and this code in my model:
public class MyModel
{
[Required(ErrorMessage="customer code req")]
[StringLength(2,ErrorMessage="must be 2 u idiot")]
public string CustomerCode {get; set;}
Though if I enter more than 2 charachters in the textbox and submit the page, in the controller when I do:
if (ModelState.IsValid)
It always says its valid? What am I missing? I have put this MVC project inside a Web Forms project but the MVC project works fine, its just the validation which is not working, any ideas? Thanks.

Make sure that the controller action accepts the model as parameter:
public ActionResult SomeAction(MyModel model)
{
if (ModelState.IsValid)
{
}
return View();
}
Now if you invoke:
http://example.com/myapp/home/someaction?customercode=123
The model should not be valid.

Hmm, it works for me on a test page with the following
public ActionResult Test()
{
MyModel model = new MyModel();
return View(model);
}
[HttpPost]
public ActionResult Test(MyModel model)
{
if (ModelState.IsValid) { }
return View(model);
}
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.CustomerCode) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.CustomerCode) %>
<%: Html.ValidationMessageFor(model => model.CustomerCode) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
public class MyModel
{
[Required(ErrorMessage = "customer code req")]
[StringLength(2, ErrorMessage = "must be 2 u idiot")]
public string CustomerCode { get; set; }
}

Related

Object reference not set to an instance of an object in MVC

I looked at all of the postings with this error but none helps. I am using MVC with the views in ASPX (C#).
I am updating records in the database after editing the data in simple views. When I process one record at a time (Controller EDIT methods and EDIT view) all works fine.
When I process multiple records (Controller UpdateTest and UPDATETEST view) I get an error in my HTTPPOST method in Controller after clicking the Submit button in a view.
here is an error with the sample codes one which works and one which does not:
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error: (CONTROLLER – SEE BELOW HttpPost UpdateTest(ICollection<Mysurvey> mysurveys)
enter code here
Line 48: public ActionResult UpdateTest(ICollection<Mysurvey> mysurveys)
Line 49: {
Line 50: foreach (var survey in mysurveys)
Line 51: {
Line 52: db.Entry(survey).State = EntityState.Modified;
Source File: C:\Users\rsc_vok\Documents\Visual Studio 2010 \Projects\MvcMysurvey\MvcMysurvey\Controllers\MysurveyController.cs Line: 50
CONTROLLER
namespace MvcMysurvey.Controllers
{
THE CODE WHICH WORKS – SINGLE EDIT
public ActionResult Edit(int id)
{
Mysurvey mysurvey = db.Mysurveys.Find(id);
return View(mysurvey);
}
// POST: /Mysurvey/Edit/5
[HttpPost]
public ActionResult Edit(Mysurvey mysurvey)
{
System.Diagnostics.Debug.WriteLine("iam in edit post");
if (ModelState.IsValid)
{
db.Entry(mysurvey).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(mysurvey);
}
THE CODE WITH THE ERROR IN httppost – MULTIPLE RECORDS SAVE
public ActionResult UpdateTest(int id = 0)
{
List<Mysurvey> mysurveys = db.Mysurveys.ToList();
return View(mysurveys.ToList());
}
[HttpPost]
public ActionResult UpdateTest(ICollection<Mysurvey> mysurveys)
{
foreach (var survey in mysurveys)
{
db.Entry(survey).State = EntityState.Modified;
}
db.SaveChanges();
return View(mysurveys);
}
VIEW
UPDATETEST
THE CODE WHICH WORKS HERE BUT THROWS AN ERROR IN CONTROLLER AFTER THE SAVE BUTTON IS HIT
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcMysurvey.Models.Mysurvey>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Updatetest
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>" type="text/javascript"></script>
<% using (Html.BeginForm()) { %>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Mysurvey</legend>
<% foreach (var item in Model) { %>
<%: Html.HiddenFor(model => item.ID) %>
<%: Html.HiddenFor(model => item.SurveyID) %>
<div class="editor-label">
<%: Html.LabelFor(model => item.Comment) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => item.Comment) %>
<%: Html.ValidationMessageFor(model => item.Comment) %>
</div>
<%} %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
MODEL
namespace MvcMysurvey.Models
{
public class Mysurvey
{
public int ID { get; set; }
[DisplayFormat(DataFormatString = "{0:c}")]
public int SurveyID { get; set; }
public string Comment { get; set; }
}
public class MysurveyDBContext : DbContext
{
public DbSet<Mysurvey> Mysurveys { get; set; }
}
}

How add data in asp.net mvc?

If I add data to table witch has no relationships, it's all good: data is adding. But if table have relationships, this is something wrong
Here is my project, what i mean is, for example AddSt in RouteController.
http://zalil.ru/32249903
Here is controller:
[HttpGet]
public ActionResult AddSt(int RouteId)
{
var routeDetails = (from rd in db.Route
join rdd in db.RouteDetail
on rd.RouteId equals rdd.Route.RouteId ///check
where rd.RouteId == RouteId
select rdd).FirstOrDefault();
return View(routeDetails);
}
[HttpPost]
public ActionResult AddSt(RouteDetail rd)
{
try
{
if (ModelState.IsValid)
{
db.AddToRouteDetail(rd);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (Exception e)
{
ModelState.AddModelError("Error!", e);
}
return View();
}
and view:
<% using (Html.BeginForm("AddSt","Route")) {%>
<%= Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Route.RouteId)%>
<%= Html.TextBoxFor(model => model.Station)%>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
Why I can't write model => model.RouteId ????
What's wrong?
Why TrainSheduleDBEntities table RouteDetail doesn't generate field RouteID ?
You are only selecting RouteDetail (rdd)
So you want model.RouteId
Just stick a debug on the addst action.
Have a look what's in rd.
I'm guessing that there's no valid routeid in it.

MVC server side validation with ASP.net

I am trying to put server side validation for a textbox in MVC website. Here is what I have:
<% using (Html.BeginForm("WebsiteLinks", "Home", FormMethod.Get))
{%>
<%: Html.ValidationSummary("Please enter valid URL and try again.") %>
<fieldset>
<p>
<%=Html.Label("Please enter URL:") %>
<%=Html.TextBox("url")%>
<%= Html.ValidationMessage("url", "*") %>
<input type="submit" value="Crawl" />
</p>
</fieldset>
<% } %>
And in the controller I have this:
public ActionResult WebsiteLinks(string url)
{
if (Regex.IsMatch(url, #"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?"))
{
ViewData["AnchorText"] = url;
return View(new Website(url, "Url"));
}
return RedirectToAction("Index");
}
The validation is working fine, but what I want to achieve is if the data is not valid, if the data is not proper url, I want to redirect to the same default page with a message probably here: <%= Html.ValidationMessage("url", "*") %> but I don't know how to do that.
Edit
After I did all the changes recommended below, I am getting an error in the header of the view page. I have Inherits="ViewPageBase<Home>" where Home is the name of the class, Home.cs in the Models folder.
In the home.cs file I have this:
namespace LAX.Models
{
public class UrlModel
{
[Required]
[DisplayName("Please enter URL:")]
[RegularExpression(#"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?")]
public string Url { get; set; }
}
}
in the controller I have:
[HttpPost]
public ActionResult WebsiteLinks(UrlModel model)
{
/*
if (Regex.IsMatch(url, #"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?"))
{
ViewData["AnchorText"] = url;
return View(new Website(url, "Url"));
}
else
{
ModelState.AddModelError("url", "Error URL Format");
}
return RedirectToAction("Index");
*/
if (ModelState.IsValid)
{
ViewData["AnchorText"] = model.Url;
return View(new Website(model.Url, "Url"));
}
return RedirectToAction("Index");
}
and in the view I have:
<% using (Html.BeginForm("WebsiteLinks", "Home", FormMethod.Get))
{%>
<%: Html.ValidationSummary("Please enter valid URL and try again.") %>
<fieldset>
<p>
<%=Html.LabelFor(m => m.Url) %>
<%=Html.TextBoxFor(m => m.Url) %>
<%=Html.ValidationMessageFor(m => m.Url) %>
<input type="submit" value="Crawl" />
</p>
</fieldset>
<% } %>
Here is the error: "The type or namespace name 'Home' could not be found (are you missing a using directive or an assembly reference?)"
public ActionResult WebsiteLinks(string url)
{
if (Regex.IsMatch(url, #"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?"))
{
ViewData["AnchorText"] = url;
return View(new Website(url, "Url"));
}
else
{
ModelState.AddModelError("url", "*");
}
return RedirectToAction("Index");
}
or you can make this sexier with DataAnnotations, Model, and a strongly typed View
Model:
public class UrlModel
{
[Required]
[DisplayName("Please enter URL:")]
[RegularExpression(#"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?")]
public string Url { get; set; }
}
Controller:
public ActionResult WebsiteLinks(UrlModel model)
{
if (ModelState.IsValid)
{
ViewData["AnchorText"] = model.Url;
return View(new Website(model.Url, "Url"));
}
return RedirectToAction("Index");
}
View:
<%# Page Language="C#" Inherits="ViewPageBase<UrlModel>" %>
<% using (Html.BeginForm("WebsiteLinks", "Home", FormMethod.Get)) {%>
<%: Html.ValidationSummary("Please enter valid URL and try again.") %>
<fieldset>
<p>
<%=Html.LabelFor(m => m.Url) %>
<%=Html.TextBoxFor(m => m.Url) %>
<%=Html.ValidationMessageFor(m => m.Url) %>
<input type="submit" value="Crawl" />
</p>
</fieldset>
<% } %>

ASP.NET MVC 2 edit controller doesn't work using viewmodel

Hey, the problem is that edit controller in ASP.NET MVC 2 doesn't work. I tried many ways and nothing works.
Here's a sample code:
[Authorize]
public ActionResult Edit() {
var edit = new UserViewModel {
User = Database.Users.Single(u => u.UserName == User.Identity.Name)
};
return View(edit);
}
[Authorize]
[HttpPost]
public ActionResult Edit(FormCollection formCollection) {
var edit = new UserViewModel {
User = Database.Users.Single(u => u.UserName == User.Identity.Name)
};
// TODO: try, catch
UpdateModel(edit, "User");
Database.SaveChanges();
return View(edit);
}
Here's a view model class:
public class UserViewModel {
public User User { get; set; }
}
What should I do to update this user model to database? A the moment I'm using only Email field:
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) {%>
<div>
<div class="UserFieldLeft"><%: Html.LabelFor(model => model.User.Email) %></div>
<div class="UserFieldRight"><%: Html.TextBoxFor(model => model.User.Email, new { style="width: 200px" }) %></div>
<div class="UserFieldHelper"><%: Html.ValidationMessageFor(model => model.User.Email) %></div>
<p><input class="UserFieldInput" type="submit" value="Zmień email" /></p>
</div>
<% } %>
If I work on native user model it doesn't work too. What's wrong? Where did I made a mistake?
By the way, I've to use view model to add (in future) some checkboxes (hair color, length, etc.) to my user.
Thank you for your time and help.
You don't need the prefix "User".
UpdateModel(edit);
should work. In the formsCollection their should be a key with User.Email. This should map to the Email property in the User Object.

Create view is posting null objects

Should be an easy question to answer.
I am trying to create an object in a view. The class that contains the object consists of a User class and a password.
When I click on the submit button, the Controller picks up null values for Password and User.
See below the Container class, the Controller and the View;
public class UserExtended
{
public UserITOC User { get; set; }
public string Password { get; set; }
}
[Authorize]
public ActionResult Create()
{
return View(new UserExtended());
}
//
// POST: /Dinners/Create
[Authorize(Roles = "Administrator")]
[HttpPost]
public ActionResult Create(UserExtended user)
{
if (ModelState.IsValid)
{
// Create user in the User datatable
SqlUsersRepository sqlRepository = new SqlUsersRepository();
ITOCEntities db = new ITOCEntities();
db.UserITOCs.AddObject(user.User);
// Create user as an authenticated user within the Reader role.
int i = user.User.EmailAddress.IndexOf('#') - 1;
string userName = user.User.EmailAddress.Substring(0, i);
string email = user.User.EmailAddress;
Membership.CreateUser(userName, user.Password, email);
Roles.AddUserToRole(userName, "Reader"); // Automatically assigned as a Reader
}
return View(new UserExtended());
}
" %>
Create
<h2>Create</h2>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.User.Forename) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.User.Forename)%>
<%: Html.ValidationMessageFor(model => model.User.Forename)%>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.User.Surname) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.User.Surname)%>
<%: Html.ValidationMessageFor(model => model.User.Surname)%>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.User.EmailAddress) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.User.EmailAddress)%>
<%: Html.ValidationMessageFor(model => model.User.EmailAddress)%>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Password) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Password)%>
<%: Html.ValidationMessageFor(model => model.Password) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
Extremely simple solution:
Change your action-signature from
public ActionResult Create(UserExtended user)
to
public ActionResult Create(UserExtended UserExtended)
That way the ModelBinder will know how to reassemble the object from Request.
Hope this helps!
I had a very similar problem, but found in my case that I had to match the database table name rather than the type name
Name of the type: NonTradingDay
Database table name: dbo.NonTradingDays (had been pluralized)
Create Method:
[HttpPost]
public ActionResult Create(NonTradingDay NonTradingDays)
{
if (ModelState.IsValid)
{
db.NonTradingDay.Add(NonTradingDays);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(NonTradingDays);
}
I had tried 'NonTradingDay', but still got null; I then looked at the database table name, tried 'NonTradingDays' and the mapping was made (the argument was no longer null).
I think this was because I had the database context as:
public DbSet<NonTradingDay> NonTradingDay { get; set; }
Rather than:
public DbSet<NonTradingDay> NonTradingDays { get; set; }
you are returning a new instance of UserExtended class
return View(new UserExtended());
instead return the object you get as the parameter
return user

Resources