Getting a "Resource not found when adding [HttpPost] to Edit method - c#

The error message I get:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Member/EditMember
My Actionlink that calls the Edit method looks like this:
#Html.ActionLink("Rediger", "EditMember", new { item.MemberID })
And the view that represents the EditMember page:
#using (Html.BeginForm("EditMember", "Member", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.MemberID)
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "Navn skal angives", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div
...
}
And the controller action:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditMember(Member model)
{
Member members = new Member();
var member = DBContext.Members.Find(model.MemberID);
if (member == null)
{
return HttpNotFound();
}
if(ModelState.IsValid)
{
DBContext.SaveChanges();
}
return View(member);
}
I have also tried to change the action methods parameter so it looks like this
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditMember(int? id) { ... }
But the error remains the same.
HOWEVER...
If I remove the [HttpPost annotation, then the error dissappears, and it will find the requested URL. But it just won't submit the changes and save them to the database.
That is, if I do:
[ValidateAntiForgeryToken]
public ActionResult EditMember(Member model)
Then it finds the requested URL, but doesn't save the changes to the database.
What might be my problem?

I suspect you are not passing the Id in the HttpGet method. This could be as a result of using a ViewModel to display member info.
There is no row in the table with the specified member Id.
In your controller you should have two actions (HttpGet and HttpPost)
[HttpGet]
public ActionResult EditMember(int id)
{
var member = db.member..SingleOrDefault(x => x.Id == id);
if (member != null)
{
var memberViewModel = new MemberViewModel();
memberViewModel.MemberID = member.Id;
memberViewModel.FirstName = member.FirstName;
memberViewModel.LastName = member.LastName;
return View(memberViewModel);
}
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditMember(Member model)
{
Member members = new Member();
var member = DBContext.Members.Find(model.MemberID);
if (member == null)
{
return HttpNotFound();
}
if(ModelState.IsValid)
{
DBContext.SaveChanges();
}
return View(member);
}

Related

populating dropdown menu from database in ASP.NET MVC [duplicate]

This question already has answers here:
Populating a razor dropdownlist from a List<object> in MVC
(9 answers)
Closed 3 years ago.
I have a view to create an 'Appointment' after choosing some options in 3 different drop-down menus (Patient, Doctor, Clinic)
I need help with creating and populating these 3 drop-down menus.
I'm pretty new to ASP.NET MVC and C#. So, your help is most appreciated.
I'll include the appointment controller and appointment creation view code.
AppointmentController
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ClinicManagement.Models;
namespace ClinicManagement.Controllers
{
public class AppointmentController : Controller
{
// GET: Appointment
public ActionResult Index()
{
using (HospitalDatabaseEntities DataBase = new HospitalDatabaseEntities())
{
return View(DataBase.Appointments.ToList());
}
}
// GET: Appointment/Details/5
public ActionResult Details(int id)
{
using (HospitalDatabaseEntities DataBase = new HospitalDatabaseEntities())
{
return View(DataBase.Appointments.Where(x => x.AppintID == id).FirstOrDefault());
}
}
// GET: Appointment/Create
public ActionResult Create()
{
return View();
}
// POST: Appointment/Create
[HttpPost]
public ActionResult Create(Appointment appointment)
{
try
{
using (HospitalDatabaseEntities DataBase = new HospitalDatabaseEntities())
{
DataBase.Appointments.Add(appointment);
DataBase.SaveChanges();
}
// TODO: Add insert logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
// GET: Appointment/Edit/5
public ActionResult Edit(int id)
{
using (HospitalDatabaseEntities DataBase = new HospitalDatabaseEntities())
{
return View(DataBase.Appointments.Where(x => x.AppintID == id).FirstOrDefault());
}
}
// POST: Appointment/Edit/5
[HttpPost]
public ActionResult Edit(int id, Appointment appointment)
{
try
{
using (HospitalDatabaseEntities DataBase = new HospitalDatabaseEntities())
{
DataBase.Entry(appointment).State = EntityState.Modified;
DataBase.SaveChanges();
}
// TODO: Add update logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
// GET: Appointment/Delete/5
public ActionResult Delete(int id)
{
using (HospitalDatabaseEntities DataBase = new HospitalDatabaseEntities())
{
return View(DataBase.Appointments.Where(x => x.AppintID == id).FirstOrDefault());
}
}
// POST: Appointment/Delete/5
[HttpPost]
public ActionResult Delete(int id, FormCollection collection)
{
try
{
// TODO: Add delete logic here
using (HospitalDatabaseEntities DataBase = new HospitalDatabaseEntities())
{
Appointment appointment = (DataBase.Appointments.Where(x => x.AppintID == id).FirstOrDefault());
DataBase.Appointments.Remove(appointment);
DataBase.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
}
Appointment 'Create' View
#model ClinicManagement.Models.Appointment
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Appointment</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.DoctorID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DoctorID, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.DoctorID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PatientID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PatientID, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PatientID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ClinicID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ClinicID, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ClinicID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create Appointment" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
If the drop down menu options are in a database, why not add a list to your model, populate that list in your GET ActionMethod and then render it using the DropdownListFor helper tag.
For example...
public class Appointment
{
public IEnumerable<SelectListItem> Clinic {get; set;}
//You should add this for every dropdown menu you intend to put in the list.
//I am guessing you already have a model like this as this was not in the question
}
public class Clinic
{
public int ClinicId {get; set;}
public string ClinicName {get; set;}
}
In the controller, you can then query the database for the options
public ActionResult Create()
{
var Clinic = context.Clinic.ToList();
var model = new Appointments()
{
Clinic = Clinic.Select(x => new SelectListItem
{
Value = x.ClinicId.ToString(),
Text = x.ClinicName
}
}
return View(model);
}
Like before, you would have to do this for all the fields. If you are worried about the numerous roundtrip to the database to get the values, do some research about Z.EntityFrameWork nuget pakages that lets you run batch SQL statements so you can get all three results with one database round trip.
Then in the view, you can do this...
#Html.DropDownListFor(m => m.ClinicId, Model.Clinic, "Select Clinic", new { #class = "form-control", id = "clinic" })
In Create controller GET , you should create 3 viewbag like
ViewBag.Patient = Database.Patient.ToList();
...
and in view, use dropdownlist:
#Html.DropDownList("PatientId", new SelectList(ViewBag.Accounts, "PatientId", "PatientName")), "choose the patient", new { #class = "form-control" }))

In asp.net, MVC, how to show content of original data after clicked EDIT method

I don't know if you can understand my question but I am trying to making this clear.
For now, I have some methods in my controller. And When I click Edit, it supposed to show the original things like the following. But instead of that, I got Nothing in the text boxes. I hope someone could me some advice, thanks!
Here is my Edit Method in the controller.
[HttpGet]
public ActionResult Edit(string programid)
{
Program program = db.Programs.Find(programid);
return View(program);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ProgramID,SerialNo,ProgramName,SubmissionDeadline,LevelID,DepartmentID,HierachyL1,HierachyL2,R1,R2,R3,R4,R5,AwardAmount,DateReleased,DatePosted,DateOpen,InternalDueDate,Area1,Area2,Area3,Weblink,Word,AgencyID")]Program program)
{
try
{
if (ModelState.IsValid)
{
db.Entry(program).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("All");
}
return View(program);
}
catch(DataException)
{
ModelState.AddModelError("", "Unable to save changes. Try again");
PopulateDepartmentDropDownList(program.DepartmentID);
}
return View(program);
}
For the Model, I just have some variables.
[Table("[RP_Program]")]
public class Program
{
[Key]
public string ProgramID { get; set; }
public string SerialNo { get; set; }
public string ProgramName { get; set; }
public DateTime? SubmissionDeadline { get; set; }
public int AgencyID { get; set; }
}
For the view, Here is part of it, most codes are the same.
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Program</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ProgramID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProgramID, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProgramID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SerialNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SerialNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SerialNo, "", new { #class = "text-danger" })
</div>
</div>
What you need to fix is changing argument name to match controller action method argument in ActionLink helper:
View
#Html.ActionLink("Edit", "Edit", "ControllerName", new { programid = item.ProgramID })
Controller
public ActionResult Edit(string programid)
{
Program program = db.Programs.Find(programid);
return View(program);
}
The previous setup tries to pass the value into id argument which doesn't actually exist in Edit action method:
// incorrect
#Html.ActionLink("Edit", "Edit", new { id = item.ProgramID })
The problem is the parameter names don't match. ASP.NET matches the names to see which parameter gets which value. So in using:
#Html.ActionLink("Edit", "Edit", new { id = item.ProgramID })
You are sending a parameter with name id, but your Edit routine is looking for a parameter called programid:
public ActionResult Edit(string programid)
You need to change one of the parameter names so that they match.

Require field validator is not working in ASP.NET MVC

Following is my code and I don't know why my validator is not working
First code is User model then second is home controller and last is view of the Index action result.I am new to MVC.COuld you please help me.
Thanks
public class User
{
[Required(ErrorMessage = "UserName is required")]
public string UserName { get; set; }
[Required(ErrorMessage = "Password is required")]
public string Pasword { get; set; }
}
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string uname,string pass)
{
if(ModelState.IsValid)
{
User user = new User();
user.UserName = uname;
user.Pasword = pass;
string Username = ConfigurationManager.AppSettings["username"].ToString();
string passwrd = ConfigurationManager.AppSettings["password"].ToString();
if (user.UserName !=null && user.Pasword !=null)
{
if(user.UserName==Username && user.Pasword==passwrd)
{
return RedirectToAction("Detail", "Home");
}
}
}
return View("Index");
}
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.UserName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.UserName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Pasword, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Pasword, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Pasword, "", new { #class = "text-danger" })
</div>
</div>
first of all you should send model instead of individual properties like
[HttpPost]
public ActionResult Index(User user)
{
if(!ModelState.IsValid)
{
return View("Index",user);
}
// your code here if model is valid
return View("Index");
}
it will check if ModelState is Invalid it will redirect to the same view with ModelState which will include key and value so if validation of a property fails its name will be the key and message will be in the value of the key validation messages will be populated according to their keys(property names)

How to insert all questions in one form?

Got 3 tables :
Question (QuestionId,QuestionText)
Survey(SurveyId,QuestionId,UserId,AnswerTExt,Comment)
User(UserId,UserName)
How to make a form in a view for all questions in table question .
Example I got 90 questions , when I answer this form 5 times , Table answers must have 450 records
Controller:
public class SurveysController : Controller
{
private TESTEntities db = new TESTEntities();
// GET: Surveys
public ActionResult Index()
{
var surveys = db.Surveys.Include(s => s.Question).Include(s => s.User);
return View(surveys.ToList());
}
// GET: Surveys/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Survey survey = db.Surveys.Find(id);
if (survey == null)
{
return HttpNotFound();
}
return View(survey);
}
// GET: Surveys/Create
public ActionResult Create()
{
ViewBag.QuestionId = new SelectList(db.Questions, "QuesionId", "QuestionText");
ViewBag.UserId = new SelectList(db.Users, "UserId", "Name");
return View();
}
// POST: Surveys/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "SuerveyId,UserId,QuestionId,Answer,Comment")] Survey survey)
{
if (ModelState.IsValid)
{
db.Surveys.Add(survey);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.QuestionId = new SelectList(db.Questions, "QuesionId", "QuestionText", survey.QuestionId);
ViewBag.UserId = new SelectList(db.Users, "UserId", "Name", survey.UserId);
return View(survey);
}
// GET: Surveys/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Survey survey = db.Surveys.Find(id);
if (survey == null)
{
return HttpNotFound();
}
ViewBag.QuestionId = new SelectList(db.Questions, "QuesionId", "QuestionText", survey.QuestionId);
ViewBag.UserId = new SelectList(db.Users, "UserId", "Name", survey.UserId);
return View(survey);
}
// POST: Surveys/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "SuerveyId,UserId,QuestionId,Answer,Comment")] Survey survey)
{
if (ModelState.IsValid)
{
db.Entry(survey).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.QuestionId = new SelectList(db.Questions, "QuesionId", "QuestionText", survey.QuestionId);
ViewBag.UserId = new SelectList(db.Users, "UserId", "Name", survey.UserId);
return View(survey);
}
// GET: Surveys/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Survey survey = db.Surveys.Find(id);
if (survey == null)
{
return HttpNotFound();
}
return View(survey);
}
// POST: Surveys/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Survey survey = db.Surveys.Find(id);
db.Surveys.Remove(survey);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
Create View:
#model TEST.Models.Survey
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Survey</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.UserId, "UserId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("UserId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.UserId, "", new { #class = "text-danger" })
</div>
</div>
#foreach (var item in ViewBag.QuestionId)
{
<div class="form-group">
#Html.LabelFor(model => model.QuestionId, "QuestionId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.HiddenFor(s=>s.QuestionId)
#Html.ValueFor(s =>item)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Answer, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Answer, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Answer, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comment, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Comment, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comment, "", 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")
</div>
First I want to make sure I understand what you are trying to do.
In your Create action you are getting all the Questions from the Question table and adding them to the View bag as QuestionId.
Assuming that when you debug the code, you see the correct data in Viewbag.QuestionId when you try to print your label to the screen with
#Html.LabelFor(model => model.QuestionId, "QuestionId", htmlAttributes: new { #class = "control-label col-md-2" })
You are trying to print out the object of QuestionId. I think you need to use 'item' in your label because this changes as your code iterates through the collection.
item.Question
should be used where you want to print out the text of the question

Using same partial view for edit and new operations

.NET 4.51, MVC 5
I have a view Edit.cshtml as follows:
#model EnergyMission.Country.Dtos.GetCountryOutput
#{
ViewBag.Title = "Edit Country";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.Partial("_AddEditPartial", new ViewDataDictionary { { "ActionName", "Edit" } })
and then New.cshtml as follows:
#model EnergyMission.Country.Dtos.GetNewCountryOutput
#{
ViewBag.Title = "New Country";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.Partial("_AddEditPartial", new ViewDataDictionary { { "ActionName", "Create" } })
Note from the above that:
Each one has a different model namely GetCountryOutput and GetNewCountryOutput. Both of these have the same properties. Currently they cannot be made the same class for other reasons.
I pass the action name so that I can use it in the Html.BeginForm in the partial view
I still need to figure out how to pass the model type to the partial view
The _AddEditPartial.cshtml looks as follows:
#model EnergyMission.Country.Dtos.GetCountryOutput
<h3>#ViewData["ActionName"]</h3>
#using (Html.BeginForm(#ViewData["ActionName"], "Countries"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>CountryTableModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.AbbreviationCode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.AbbreviationCode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.AbbreviationCode, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.InternationalCountryDialCode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.InternationalCountryDialCode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InternationalCountryDialCode, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
</div>
}
My questions are as follows:
Is there an easier way to share a common data entry layout for Add / Edit operations that whay I am doing above?
If I were to follow the approach described how do I:
Pass the model type to the partial view. Is it something like:
_
#Html.Partial("_AddEditPartial", new ViewDataDictionary { { "ActionName", "Create" }, {"ModelTypeName", "EnergyMission.Country.Dtos.GetCountryOutput"} })
and then in _AddEdit.cshtml
_
#model typeof(#ViewData["ModelTypeName"])
Why is the following not valid:
_
#using (Html.BeginForm(ViewData["ActionName"], "Countries"))
as that gives me a compile time error.
Create a single view, then use your controller to direct to a single view and use your repository to insert/update accordingly in a Save method. However, please note, in the example below you will need to make sure the model is the same - based on the principle that you should remove duplication. If that's not possible consider using a dynamic model in your view or using the ViewModel you can map the properties accordingly (anyway I don't want to over complicate the answer as I'm hoping this provides the solution you need - give or take some refactoring here and there).
A simplified example of the controller and repository (using a viewmodel)....
public class ProductController : Controller
{
private IProductRepository _repository;
public ProductController(IProductRepository productsRepository)
{
this._repository = productsRepository;
}
public ViewResult Edit(int productID)
{
ProductEditViewModel model = new ProductEditViewModel
{
Product = this._repository.Products.Where(m => m.ProductID == productID).FirstOrDefault()
};
return View(model);
}
[HttpPost]
public ActionResult Edit(int productId)
{
ProductEditViewModel model = new ProductEditViewModel
{
Product = _repository.Products.First(m => m.ProductID == productId)
};
TryUpdateModel(model);
if (ModelState.IsValid)
{
_repository.Save(model.Product);
return RedirectToAction("Index");
}
else
{
return View(model);
}
}
public ViewResult Create()
{
return View("Edit", new Product());
}
[HttpPost]
public ActionResult Create(Product product)
{
return Edit(product.ProductID);
}
}
The repository....
public class SqlProductRepository : IProductRepository
{
private MyDataContext db;
private Table<Product> _productsTable;
public IQueryable<Product> Products
{
get { return _productsTable; }
}
public void Save(Product product)
{
if (product.ProductID == 0)
{
_productsTable.InsertOnSubmit(product);
}
else if (_productsTable.GetOriginalEntityState(product) == null)
{
_productsTable.Attach(product);
_productsTable.Context.Refresh(RefreshMode.KeepCurrentValues, product);
}
_productsTable.Context.SubmitChanges();
}
}
Well the answer to 3. is that html.beginform expects a string as its first parameter, and as you are using ViewData which is a
Dictionary<string, object>
you need to cast your value as a string:
#using (Html.BeginForm(ViewData["ActionName"] as string, "Countries"))
For 1. You could try deriving both of your dto classes from a base class and setting that class as the model type for both the add and edit views

Categories

Resources