Object reference not set to an instance of an object in MVC - asp.net-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; }
}
}

Related

The type or namespace name 'DinnerForm' does not exist in the namespace 'NerdDinner.Models' when trying to implement partial form

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS0234: The type or namespace name 'DinnerForm' does not exist in the namespace 'NerdDinner.Models' (are you missing an assembly reference?)
Source Error:
Line 170:
Line 171: [System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
Line 172: public class views_dinners_create_aspx : System.Web.Mvc.ViewPage, System.Web.SessionState.IRequiresSessionState, System.Web.IHttpHandler {
Line 173:
Line 174: private static bool #__initialized;
DinnerFormViewModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NerdDinner.Controllers;
namespace NerdDinner.Models
{
public class DinnerFormViewModel
{
// Properties
public Dinner Dinner { get; private set; }
public SelectList Countries { get; private set; }
// Constructor
public DinnerFormViewModel(Dinner dinner)
{
Dinner = dinner;
Countries = new SelectList(PhoneValidator.Countries, dinner.Country);
}
}
}
DinnerForm.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NerdDinner.Controllers.DinnerFormViewModel>" %>
<%= Html.ValidationSummary("Please correct the errors and try again.") %>
<% using (Html.BeginForm()) { %>
<fieldset>
<p>
<label for="Title">Dinner Title:</label>
<%= Html.TextBox("Title", Model.Dinner.Title) %>
<%=Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="EventDate">Event Date:</label>
<%= Html.TextBox("EventDate", Model.Dinner.EventDate) %>
<%= Html.ValidationMessage("EventDate", "*") %>
</p>
<p>
<label for="Description">Description:</label>
<%= Html.TextArea("Description", Model.Dinner.Description) %>
<%= Html.ValidationMessage("Description", "*") %>
</p>
<p>
<label for="Address">Address:</label>
<%= Html.TextBox("Address", Model.Dinner.Address) %>
<%= Html.ValidationMessage("Address", "*") %>
</p>
<p>
<label for="Country">Country:</label>
<%= Html.DropDownList("Country", Model.Countries) %>
<%= Html.ValidationMessage("Country", "*") %>
</p>
<p>
<label for="ContactPhone">Contact Phone #:</label>
<%= Html.TextBox("ContactPhone", Model.Dinner.ContactPhone) %>
<%= Html.ValidationMessage("ContactPhone", "*") %>
</p>
<p>
<input type="submit" value="Save"/>
</p>
</fieldset>
<% } %>
DinnersControllers.cs (create methods)
//
// GET: /Dinners/Create
public ActionResult Create()
{
Dinner dinner = new Dinner()
{
EventDate = DateTime.Now.AddDays(7)
};
return View(new DinnerFormViewModel(dinner));
}
//
// POST: /Dinners/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Dinner dinner)
{
if (ModelState.IsValid)
{
try
{
dinner.HostedBy = "SomeUser";
dinnerRepository.Add(dinner);
dinnerRepository.Save();
return RedirectToAction("Details", new { id = dinner.DinnerID });
}
catch
{
foreach (var issue in dinner.GetRuleViolations())
{
ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
return View(new DinnerFormViewModel(dinner));
}
}
return View(new DinnerFormViewModel(dinner));
}
Create.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Models.DinnerForm>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Host A Dinner
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Host a Dinner</h2>
<% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
DinnerForm.ascx:
Inherits="System.Web.Mvc.ViewUserControl<NerdDinner.Models.DinnerFormViewModel>

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>
<% } %>

Return a generic list to the MVC Controller

I have a class that looks like this;
public class item
{
public string Tradingname { get; set; }
}
I have a Partial View that inherits from the "item" class;
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<item>" %>
<%= Html.TextBoxFor(x => x.Tradingname) %>
In my view I create a number of them. Let's Say 2;
<% using (Html.BeginForm())
{ %>
<% Html.RenderPartial("TradingName", new Binding.Models.item()); %><br />
<% Html.RenderPartial("TradingName", new Binding.Models.item()); %><br />
<input type="submit" />
<%} %>
Then in my controller I was hoping to be able to write this;
[HttpPost]
public ActionResult Index(List<item> items)
or
[HttpPost]
public ActionResult Index([Bind(Prefix = "Tradingname")]List<item> items)
But I can't seem to get any data back from my partial views into my List. Anyone know how I can get a variable list of data back from a variable set of partialViews?
I would recommend you using editor templates:
Controller:
public class HomeController: Controller
{
public ActionResult Index()
{
List<item> model = ...
return View(model);
}
[HttpPost]
public ActionResult Index(List<item> items)
{
...
}
}
and in the view:
<% using (Html.BeginForm()) { %>
<%= Html.EditorForModel();
<input type="submit" />
<% } %>
and finally simply move the partial in ~/Views/Home/EditorTemplates/item.ascx (name and location are important):
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<item>" %>
<%= Html.TextBoxFor(x => x.Tradingname) %><br/>

Problems Passing ViewModel with data from View to Controller

Ok, here is my problem. I am trying to pass a view model of mine, which has multiple list in it, to my view. Then in my view i need to edit the different list. Then on my post i need to save the edits. Although, when i pass my viewmodel back to my post, it is empty! Can somebody explain what i am doing wrong? i am not worried about saving the information right now, i am just worried about getting the data back to the controller. The ViewModel is null when i hit that portion.
Controller
public ActionResult ManageNewsArticles()
{
NewsViewModel newsViewModel = new NewsViewModel();
newsViewModel.ListBreakingNews = db.NewsArticles.Where(n => n.PageSetupID == 1).ToList<NewsArticle>();
newsViewModel.ListMainArticle = db.NewsArticles.Where(n => n.PageSetupID == 2).ToList<NewsArticle>();
newsViewModel.ListSubNews1 = db.NewsArticles.Where(n => n.PageSetupID == 3).ToList<NewsArticle>();
newsViewModel.ListSubNews2 = db.NewsArticles.Where(n => n.PageSetupID == 4).ToList<NewsArticle>();
newsViewModel.ListSubNews3 = db.NewsArticles.Where(n => n.PageSetupID == 5).ToList<NewsArticle>();
return View(newsViewModel);
}
[HttpPost]
public ActionResult ManageNewsArticles(NewsViewModel newsViewModel)
{
if (ModelState.IsValid)
{
db.SaveChanges();
return RedirectToAction("Admin");
}
return View(newsViewModel);
}
here is my View
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<TrueNews.ViewModels.NewsViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Manage News Articles
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Manage News Articles</h2>
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm(Model)) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<%: Html.EditorForModel(Model) %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to Admin Controls", "Admin") %>
</div>
</asp:Content>
NewsViewModel
public class NewsViewModel
{
public List<NewsArticle> ListBreakingNews { get; set; }
public List<NewsArticle> ListMainArticle { get; set; }
public List<NewsArticle> ListSubNews1 { get; set; }
public List<NewsArticle> ListSubNews2 { get; set; }
public List<NewsArticle> ListSubNews3 { get; set; }
} // End of Class
I couldn't get your view to display correctly using the EditorForModel syntax, however I did replicate your problem and found this article which provides one way of solving it:
http://weblogs.asp.net/nmarun/archive/2010/03/13/asp-net-mvc-2-model-binding-for-a-collection.aspx
I created a quick table NewsArticle containing Id and Stuff columns and then had the following form in the view:
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<% for (int i = 0; i < Model.ListBreakingNews.Count; i++)
{ %>
<div>
Id</div>
<div>
<%= Html.TextBox(string.Format("ListBreakingNews[{0}].Id", i), Model.ListBreakingNews[i].Id) %>
</div>
<div>
Name</div>
<div>
<%= Html.TextBox(string.Format("ListBreakingNews[{0}].Stuff", i), Model.ListBreakingNews[i].Stuff) %>
</div>
<% } %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
and the items in the list were passed when posted. I also found that previously you had Html.BeginForm(Model) which when I added it caused nothing to be passed through in the view model - I am only a newbie to MVC so I don't know why this happens but my code below worked only with Html.BeginForm() and not Html.BeginForm(Model).
I hope this helps.

MVC Validation Not Working In Web Forms Project

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; }
}

Resources