Form submit using partail View error - asp.net-mvc

I have created a form for add comment. I have created it in main View called Index in Home controller. bellow is Index View
private projectDBEntities db = new projectDBEntities();
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
}
public ActionResult AddComment()
{
return PartialView("_Comment");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddComment(comment cmt)
{
if (ModelState.IsValid)
{
db.comments.Add(cmt);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
return PartialView("_Comment", cmt);
}
below is _Comment Partial View
#using (Html.BeginForm()) {#Html.AntiForgeryToken()#Html.ValidationSummary(true)
<fieldset>
<legend>comment</legend>
<div class="editor-label">
#Html.LabelFor(model => model.cmd_content)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.cmd_content)
#Html.ValidationMessageFor(model => model.cmd_content)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.t_email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.t_email)
#Html.ValidationMessageFor(model => model.t_email)
</div>
<p>
<input type="submit" value="Comment" />
</p>
</fieldset>}
System.Web.HttpException was occuerd. I want to know What is the reason behind this error and what is the best method to form submit using partail View.

Id have to agree with Sandip's answer here, but to elaborate ..
#using (Html.BeginForm("AddComment", "Home"))
{
//Content to send to the server-side
}
As long as your model in your partial view points to your 'Comment' object, then this should work fine when using #Html.EditorFor(). In your controller, your already waiting for your 'Comment' object to be populated. So on Post, when the submit is clicked, it will populate that object.
Hope this helps.

#using (Html.BeginForm("AddComment", "Home"))
{
}

Related

Passing data from a View to a Controller in .NET MVC - "#model" not highlighting

The following code works as I need it to:
#using (Html.BeginForm("LOLOL", "PATIENT", null))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>PATIENT</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</fieldset>
<p>
<input type="submit" value="SUBMIT" />
</p>
}
In LOLOLController:
[HttpPost]
public IActionResult LOLOL(Patient p) {
var client = new MongoClient("mongodb://localhost:27017");
var userId = _userManager.GetUserId(HttpContext.User);
string db_name = "test" + userId;
var database = client.GetDatabase(db_name);
var collection = database.GetCollection<BsonDocument>("patients");
var filter = Builders<BsonDocument>.Filter.Eq("Name", p.Name.ToString());
var document = collection.Find(filter).First();
// I'm cutting short the rest of the code, because when I do something
// similar later, "collection.Find(filter).First()" fires an exception, I'll
// explain..
return View(p);
}
I have something equivalent to taking off the fieldset element in the HTML, leaving basically just a button in the "Html.BeginForm", but then the data is clearly not binding properly, which I know because if I just have a button and no data-entry, I click the button and then I get an error saying the data cannot be found from the database. (EDIT: I now have confirmed that this is indeed because the Patient object is not being passed to the controller quite as I expected it to, seems like a brand new Patient object was created upon calling html.beginform ... I thought that maybe the old Patient object was being passed so I did not have to enter all its data members every time we use Html.BeginForm)
In sum, I want to fill out a text box, click a button to load a new page and display the value of that textbox, but have that value also persisted in essentially a session state, so that if I call another Html.BeginForm function and go into a third view, the text from the first view will be displayed in the third view, even though I did not have to type its value in the second view. Hopefully I can repeat this process, and essentially load up the data members of a class with one view per data member.
Make sure you pass the data from the previous view to the new view from your Controller. When you pass it, include #HiddenFor for those properties from the previous view in your new view. That way the new view will keep and then pass the values to your next POST.
#Html.HiddenFor(model => model.PropertyYouPassedAndWantToKeepAndPassAgain
Edit: Here's the logic for using multiple views for one object... as requested.
Model:
public class Patient
{
string Name { get; set; }
string Address { get; set; }
string City { get; set; }
}
Page1 GET:
[HttpGet]
public ActionResult Page1()
{
Patient patient = new Patient();
return View("~/Views/Page1.cshtml", patient);
}
Page 1 View... only ask for the name.
#model mysite.Models.Patient
#using (Html.BeginForm("LOLOL", "PATIENT", null))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>PATIENT</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</fieldset>
<p>
<input type="submit" value="SUBMIT" />
</p>
}
Page1 POST... get the patient and pass it on to the next view...
[HttpPost]
public ActionResult Page1(Patient patient)
{
if (ModelState.IsValid)
{
return View("~/Views/Page2.cshtml", patient); // pass your patient to the second page view with the name
}
else
{
return View("~/Views/Page1.cshtml", patient);
}
}
Page2 GET... get the patient from the prior Page1 POST and send it off to the Page2 View.
[HttpGet]
public ActionResult Page2(Patient patient)
{
// Receive patient from Page1 post and pass it to new view... includes the name
return View("~/Views/Page2.cshtml", patient);
}
Page2 View gets the object... use a HiddenFor to keep the name which you just sent from the GET.
#model mysite.Models.Patient
#using (Html.BeginForm("LOLOL", "PATIENT", null))
{
#Html.HiddenFor(model => model.Name) #* This will keep the name on your next post *#
#Html.ValidationSummary(true)
<fieldset>
<legend>PATIENT</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
</fieldset>
<p>
<input type="submit" value="SUBMIT" />
</p>
}
Since the HiddenFor holds the Name, it will be passed on your next post. It is there but hidden from the form itself.
[HttpPost]
public ActionResult Page2(Patient patient)
{
// Because of the HiddenFor, the Name will be passed because it was kept in the view... but hidden from the form itself.
// It's basically storing it for you to pass again
if (ModelState.IsValid)
{
// Pass object with Name and Address to next controller
return View("~/Views/Page3.cshtml", patient);
}
else
{
return View("~/Views/Page2.cshtml", patient);
}
}
Page2 POST
[HttpPost]
public ActionResult Page2(Patient patient)
{
// Because of the HiddenFor, the Name will be passed because it was kept in the view... but hidden from the form itself.
// It's basically storing it for you to pass again
if (ModelState.IsValid)
{
// Pass object with Name and Address to next controller
return View("~/Views/Page3.cshtml", patient);
}
else
{
return View("~/Views/Page2.cshtml", patient);
}
}
Page3 GET
[HttpGet]
public ActionResult Page3(Patient patient)
{
// Pass patient again... to your next view
return View("~/Views/Page3.cshtml", patient);
}
Page3 View...
#using (Html.BeginForm("LOLOL", "PATIENT", null))
{
#Html.HiddenFor(model => model.Name) #* Keep name again for your next post *#
#Html.HiddenFor(model => model.Address) #* Now we are keeping the address as well *#
#Html.ValidationSummary(true)
<fieldset>
<legend>PATIENT</legend>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.City)
#Html.ValidationMessageFor(model => model.City)
</div>
</fieldset>
<p>
<input type="submit" value="SUBMIT" />
</p>
}
And so on and so forth... until you have your model complete and want to do something with it.

BeginForm<TController> won't post model first time round

I have an issue using the latest mvc futures BeginForm extension. I have disabled clientsidevalidation as I have read that there may still be a bug with it. Basically the first time it gets posted the model is null, the second time (and any time after that) it will post the model fine.
It works if I switch it back to #using(Html.BeginForm()) or #using(Html.BeginForm("action", "controller" etc but I would rather make use of the strongly typed version. Here is my code:
Controller
[HandleError]
public class HomeController : BaseServiceController<IUserService>
{
public HomeController(IUserService service, IMapper mapper, ICustomPrincipal user)
: base(service, mapper, user)
{}
[AllowAnonymous]
[HttpGet]
public ActionResult Logon(string ReturnUrl)
{
LogonModel model = new LogonModel() { ReturnUrl = ReturnUrl };
return View(model);
}
[AllowAnonymous]
[HttpPost]
public ActionResult Logon(LogonModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
SfUser sfUser = service.Logon(model.UserName, model.Password);
if (sfUser == null)
{
ModelState.AddModelError("General", "Username or Password incorrect");
return View(model);
}
Response.Cookies.Add(TicketMaster.setAuthCookie(new CustomPrincipalSerializeModel(sfUser)));
return Redirect(model.ReturnUrl);
}
View
#model LogonModel
#{
ViewBag.Title = "Logon";
}
//#using(Html.BeginForm()) //Works
#using(Html.BeginForm<HomeController>(c => c.Logon(Model)))
{
#Html.HiddenFor(m => m.ReturnUrl)
<div class="editor-label">
#Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.UserName)
#Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(m => m.Password)
#Html.ValidationMessageFor(m => m.Password)
</div>
<br />
<p>
<input type="submit" value="Login" /><br />
#Html.ValidationSummary(true)
</p>
}
I could understand the problem if it always posted a null model, but only on first post? Driving me mad.
I know this is old and probably already solved somehow, but you should pass null instead of Model to the expression. That way, the model will be built using the form values.
It took me a few hours to find this. Go to the Strong Typed Html BeginForm<TController> section. This is the key point:
You want to pass your values within the form’s scope, not the
BeginForm method itself.
In your case, just change
#using(Html.BeginForm<HomeController>(c => c.Logon(Model)))
to
#using(Html.BeginForm<HomeController>(c => c.Logon(null)))

Saving forms in mvc

I'm completely new to MVC having made the decision to try make the switch from aspx WebForms.
I have created a view using the MVC view creator wizard and selected a strongly typed class and an edit Scaffold template.
I got the following
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Company</legend>
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber)
#Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
In the Controller I have the following to get the model details
[System.Web.Http.HttpGet]
public ActionResult Edit(int id)
{
var uow = new BlogUow();
var company = uow.Companies.GetById(id);
return View(company);
}
This works fine but the problem is, I'm stumped on how I actually save the newly entered details.
I relied too much on how the web forms handle post backs.
You must write a post action for your edit in the controller:
[System.Web.Http.HttpPost]
public ActionResult Edit(Companies company)
{
var uow = new BlogUow();
if (ModelState.IsValid)
{
uow.Entry(company).State = EntityState.Modified;
return RedirectToAction("Index");
}
return View(company);
}
note Companies overload
[HttpPost]
public ActionResult Edit(Companies company)
{
var uow = new BlogUow();
if (ModelState.IsValid)
{
Edit here
}
return View(company);
}

How do I call submit in mvc app?

I have mvc3 web app.
inside that I have one Enquiry form once I submit that form it should save all data into database for that I have used Entity Framework.
EnquiryController.cs
public class EnquiryController : Controller
{
aspnetdbEntities dbEntities = new aspnetdbEntities();
//
// GET: /Enquiry/
public ActionResult Index()
{
return View();
}
//
// GET: /Enquiry/
public ActionResult Enquiry()
{
return View();
}
//
//POST: /Enquiry/
[HttpPost]
public ActionResult Enquiry(Enquiry enquiry)
{
if (ModelState.IsValid)
{
dbEntities.Enquiries.AddObject(enquiry);
dbEntities.SaveChanges();
return RedirectToAction("Index");
}
return View(enquiry);
}
}
Enquiry.cshtml
#model MyWeb.Models.Enquiry
#{
ViewBag.Title = "Enquiry";
}
<h2>Enquiry</h2>
<div>
<fieldset>
<legend>Enquiry Form</legend>
<div class="editor-label">
#Html.LabelFor(m => m.FirstName)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.FirstName)
#Html.ValidationMessageFor(m => m.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.LastName)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.LastName)
#Html.ValidationMessageFor(m => m.LastName)
</div>
<p>
<input type="submit" value="Submit" />
</p>
</fieldset>
</div>
But when I clicked on Submit button it is not working no round rip no refresh
please help me where i go wrong i'm newbie.
ashuthinks,
just add the htmlHelper (for forms) to your view:
#using(Html.BeginForm()){
// exisiting fieldset stuff
<fieldset>... bla</fieldset>
}
around your fieldset and you're good to go

keeping Object Data after passing it to a strongly typed view

I have a simple ASP.NET MVC 3 site, from my Controller out of the Edit Action I pass a Object (a class which is also mapped by nhibernate)
After editing and clicking save i pass it to the [HTTPPost] decoraded Method but and all properties are correct, excerpt the "id" property it hat a guid value equivalent to NULL (00000000-0000-000...).
Is there a problem using the Domain Model to strongly type my Views? May the problem be that Id has:
{get; private set;}
???
Thanks in advance.
Here The Code:
My View:
'#model fnh.DataModel.Kunde
#{
View.Title = "EditKunde";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>EditKunde</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Fields</legend>
#Html.EditorFor(model => model._id)
#Html.EditorFor(model => model._KdNr);
<div class="editor-label">
#Html.LabelFor(model => model._Name)
`enter code here` </div>
<div class="editor-field">
#Html.EditorFor(model => model._Name)
#Html.ValidationMessageFor(model => model._Name)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
'
My Controller Actions:
' public ActionResult EditKunde(Guid id)
{
return View(_kunden.GetKundeById(id));
}
[HttpPost]
public ActionResult EditKunde(Kunde kunde)
{
Ansprechpartner anp = new Ansprechpartner();
anp._Name = "JustATry";
kunde._Ansprechpartner.Add(anp);
`enter code here` _kunden.EditKunde(kunde);
return View();
}'
Are you adding the Id property to your form (maybe as a hidden field)?
It would be useful if you post the Action code (for both Edit Actions), and the View.

Resources