The problem I am facing is that when the delete link is clicked and my delete actionResult is called it errors out saying there is no view for delete. I have tried setting ActionName("Index") but then I get an ambiguous error message regarding the View Index.
public ActionResult Index()
{
***code goes here****
return View(viewModel);
}
[HttpPost, ActionName("Index")]
[OnAction(ButtonName = "Create")]
public ActionResult Index(***code goes here***)
{
***code goes here****
return RedirectToAction("Index");
}
//GET:
public ActionResult Delete(int? id)
{
***code goes here****
return View(lansing);
}
//POST:
[HttpPost, ActionName("Index")]
[OnAction(ButtonName = "Delete")]
//[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
***code goes here****
return RedirectToAction("Index");
}
I then have one table that gets updated with information that the user puts in as well as delete information when an actionLink is clicked from the table which is handled by both of these ActionResults.
You can specify which view to render by passing the name of the view as first argument to the call of the view method (see the documentation of ASP.NET or ASP.NET Core).
But as the HTTP GET Delete method usually is used to show the user the elements to delete and prompt the user to confirm the deletion (see this ASP.NET Core tutorial), you maybe want to add a dedicated view for it.
The solution to the problem I was facing was to actually perform the the actions of the Delete Post inside of the Get Delete method, because of using one view for both Creation, Editing, and Deleting.
The end result looked like this:
public ActionResult Delete(int? id)
{
***code goes here****
var lansing = db.LansingMileages.Find(id);
viewModel.Records = new[]
{
lansing
};
db.LansingMileages.Remove(lansing);
db.SaveChanges();
return RedirectToAction("Index");
}
Related
I know there are a lot of questions about this, but not in a single one I've seen (and I've been searching for two hours now), did I see what to write in the razor view (.cshtml file) to fire the controller method associated with saving the model object to the database, or how that object is passed.
So I want to make a simple registration page. I created the Users model, created the view associated with the model, named Register.cshtml, and I access the view through the Account controller which has a Register method:
public ActionResult Register()
{
return View();
}
The tutorial I follow uses the default code generated in the View when you create it for the Users model.
<input type="submit" value="Create" class="btn btn-default" />
And states that you should make a method in the Account Controller as follows:
public ActionResult Register(User obj)
{
if (ModelState.IsValid)
{
DatabaseEntities db = new DatabaseEntities();
db.Users.Add(obj);
db.SaveChanges();
}
return View(obj);
}
(where DatabaseEntities is the name of my database)
This doesn't work, because, on running the application, it says that it doesn't know which one of the two methods to fire.
System.Web.Mvc.ActionResult Register() on type Biblioteca.Controllers.AccountController
System.Web.Mvc.ActionResult Register(Biblioteca.Models.User) on type Biblioteca.Controllers.AccountController
This is the error I get.
I thought of renaming the second method RegisterPost(User obj), but then I don't know how to call the method with the argument, because in the razor view, I don't know which is the object that gets created on submitting the form.
I could use an #Html.ActionLink(), but I don't know how to send the object.
I actually tried adding an onclick method to the submit button, as follows:
onclick="location.href='#Url.Action("RegisterPost", "Account")'"
But after filling the form and clicking the submit button, nothing happens. Nothing gets inserted into the database.
I don't know what to do now. Please help.
Add attribute [HttpGet] to the first action and [HttpPost] to the second action:
[HttpGet]
public ActionResult Register()
{
return View();
}
[HttpPost]
public ActionResult Register(User obj)
{
if (ModelState.IsValid)
{
DatabaseEntities db = new DatabaseEntities();
db.Users.Add(obj);
db.SaveChanges();
}
return View(obj);
}
You can read more on MSDN
To expand a bit, try adding [HttpPost] above the second Action method.
[HttpPost]
public ActionResult Register(User obj)
{
if (ModelState.IsValid)
{
DatabaseEntities db = new DatabaseEntities();
db.Users.Add(obj);
db.SaveChanges();
}
return View(obj);
}
I have an ASP.net application with a [HttpGet] for a view an ActionResult named 'Create' on a Controller called Students
My 'Student' is then posted to the following controller.
[HttpPost]
public async Task<ActionResult> Create(Student student)
{
Student.Add(student);
if (ModelState.IsValid)
{
var result = db.Students.Add(student);
await db.SaveChangesAsync();
return Details(result);
}
return View(new CreateStudent());
}
return Details(result); is the line I'm interested in.
Previously I had RedirectToAction where I passed in the result. Id property and used a GET request to query a database.
But, I'm not wanting to have a URL like 'students/details/id=123' Or 'students/details/123' I want to Post my model to the controller 'students/details'
var result is a single 'Student'and my 'Details' ActionResult looks like this:
[HttpPost]
public async Task<ActionResult> Details(Student student)
{
//
}
but return Details(result); doesn't work, I receive an error message stating:
'The model item passed into the dictionary is of type 'LinkApp.Models.Student', but this dictionary requires a model item of type 'LinkApp.Models.DTOs.CreateStudent'.'
But I believe this is because my URL never goes to '/Students/Details', my URL still shows '/Students/Create'
Any help is appreciated. And again, if it's not clear, please ask for any clarity
Thanks
EDIT DUE TO ME NOT BEING VERY CLEAR ;)
So I'm a little bit confused with what you're trying to achieve.
Here is what I've gathered: You want to POST the data. Right now you have a GET method. You can think of a GET method like something that retrieves, and a POST as something that gives.
So your GET method should not be trying to POST anything.
Your GET method should looks like it should be a POST since you're trying to "give" the data to something, not get the data.
[HttpPost]
public async Task<ActionResult> Create(Student student)
{
Student.Add(student);
if (ModelState.IsValid)
{
var result = db.Students.Add(student);
await db.SaveChangesAsync();
return View("Details", result);
}
return View(); //You should add a property to the model called ErrorMessage or something like that, then you could do student.ErrorMessage = "Model state was not valid";, then you could do return View(student); and in the view you could do something like #if (Model.ErrorMessage != null) { #Html.DisplayFor(m=>m.ErrorMessage); }
}
This is what your post should look like, you're saving the Student model to the database and returning to a view.
Now your GET should just be something like this:
[HttpGet]
public ActionResult Create()
{
return View();
}
Edit:
If you wanted your post to do the error message I left in the comment above you would just do this right above the second return View();
student.ErrorMessage = "Model state was not valid;" //Or whatever you want to say
return View(student);
Then in your view you would have something like this:
#if (student.ErrorMessage != null)
{
#Html.DisplayFor(m => m.ErrorMessage);
}
I am trying to pass a textbox's text back to a method in my controller, but the data is not being passed in the parameter
I am genuinely confused, i'm following another example but i'm getting a different result, ie - my method behaving as if no parameter is passed
Code
public ActionResult Index(string searchString)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
var listOfAnimals = db.Animals.ToList();
if (!String.IsNullOrEmpty(searchString))
{
listOfAnimals = listOfAnimals.Where(a => a.AnimalName.ToLower().Contains(searchString.ToLower())).ToList();
}
return View(listOfAnimals);
}
and here is my razor form from my view page
#using(Html.BeginForm("Index", "Home"))
{
#Html.TextBox("searchString")
<input type="submit" id="Index" value="Index" />
}
Can anybody spot why this isn't working?
If more code is needed, please let me know but i think the issue is isolated to here
You code is correct.
Since you didn't add [HttpGet] or [HttpPost] before index method.
This method was called twice.
The first call ran when producing the page with form via url http://server/Home/Index. This call was an http get and searchString mapped from URL was null, which is correct.
The second call ran when you clicked submit button. Correct value would be mapped by MVC correctly.
You need to have 2 Index actions (two methods), one without decorations (GET verb) and another one decorated with HttpPost (POST verb). Basically, when you go to the index page, the GET action is executed. When you submit the form, a POST request is executed and the Index decorated with HttpPost is executed.
// GET
public ActionResult Index() { ... }
// POST
[HttpPost]
public ActionResult Index(string searchString) { ... }
Francisco Goldenstein wrote the recommended way. It means you can have two Index() actions:
// for GET
public ActionResult Index() { ... }
// for POST
[HttpPost]
public ActionResult Index(string searchString) { ... }
However it is possible to have one Index() method for handling both (GET and POST) requests:
public ActionResult Index(string searchString = "")
{
if(!string.IsNullOrEmpty(searchString)
{ /* apply filter rule here */ }
}
You wrote, your code is not working. Do you mean, your action method is not requested after click on the button? Consider to allow empty value Index(string searchString = "")
If your action method is fired but variable is empty, check the name on the View() side. Textbox must not be disabled, of course.
I have two problems;
First, I can not go to the main page URL. It is not working as it is on the login page:
public ActionResult Index()
{
return View();
}
public ActionResult Login(string email, string password)
{
model = BLcontext.GetUserLogin(email, password);
if (model.UserID > 0)
{
return Redirect("/Home/Index");
or return PartialView("Index");
or return RedirectToAction("Index");
}
return PartialView("Login");
}
Second, how can I get userId value?
clientAuth "c495600a-71b3-44cb-a577-634426597c82,{\"UserID\":2,\"CurrentSessionID\":\"00000000-0000-0000-0000-000000000000\"},16.01.2015 15:50:53"
I did it
clientAuth.Split(',')[1]
but I see it.. I want value 2
return :"{\"UserID\":2"
I'm not entirely sure what or where your problem is based on what you've submitted. However, it should be as easy as this:
Home Controller: (Default Defined in your Routes)
public ActionResult Index()
{
return View();
}
By default that is a Get, which will automatically be returned when you call the raw controller.
On your other page, when you have an Event that occurs from a user interaction, you simply declare the method and direct to proper action like:
[HttpPost]
public ActionResult ValidateCustomer(int? id)
{
if(id != null)
return View("/SomeOtherController/Example");
return View("/Home/Index");
}
That would take the <form action="/Home/ValidateCustomer" method="POST"> and automatically force the submit input to pass your parameter in your fields, then go to the ActionResult ValidateCustomer hopefully this clarifies navigation a bit for you.
I am fairly new to MVC and i'm looking for advice on how to setup a particular registration controller.
I have a controller called AccountController which has a Register method and I have a Register.cshtml.
Now, one of the biggest problems I seem stuck on is that I have 2 dropdowns that I need to populate based on the response from a service as these values change depending on location and other various parameters.
I have my page started and loading but I'm not sure what to do once a user click 'register'.
#model Adw.Models.RegisterModel //This is my model
#Html.DropDownListFor(m => m.States, new SelectList(Model.States)); // I load my dropdowns here
[AllowAnonymous]
public ActionResult Register(RegisterModel model)
{
model.States = Services.GetStates().Payload;
model.Countries = Services.GetCountries().Payload;
return View(model);
}
So my question is, when a user submits the form, should it come back to this same method? If so what would be the best way to validate that this is a submit rather than an initial load?
Also i haven't done much in the way of error handling and could use a suggestion on that, such as if either of the above service calls fail, then a registration cannot be completed, should that direct to a new page or is there a easy way to build that kind of error into the same page?
You should create two different method. One for GET and second for POST request:
[AllowAnonymous]
[HttpGet]
public ActionResult Register()
{
...
}
[AllowAnonymous]
[HttpPost]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// create user
return this.RedirectToAction("SignIn");
}
else
{
return View(model);
}
}
You can review sample from default template.