making HTTP post request with confirmation message for delete - asp.net-mvc

I want to delete an item by getting confirmation from user & I want to delete it with POST method.
Here's my code snippet
#Html.ActionLink("Delete","Delete",new { id=item.UserId },new AjaxOptions {HttpMethod = "POST", Confirm = "Do you really want to delete this?"})
& my action method is:
[HttpPost]
public ActionResult Delete(int? id, LearningMVC.Models.User userDetails)
{
try
{
var dbContext = new MyDBDataContext();
var user = dbContext.Users.FirstOrDefault(userId => userId.UserId == id);
if (user != null)
{
dbContext.Users.DeleteOnSubmit(user);
dbContext.SubmitChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
If I remove the [HttpPost] attribute, It just deletes the record without any confirmation. It's giving 404 error with [HttpPost] attribute.
I have included jquery-1.5.1.min.js, unobtrusive-ajax.js, MicrosoftAjax.js, MicrosoftMvcAjax.js in the said order in layout page.
what I am missing here?

I believe that you wanted to write:
#Ajax.ActionLink("Delete", "Delete",
new { id = item.UserId },
new AjaxOptions { HttpMethod = "POST", Confirm = "Do you really want to delete this?" })
Just use AjaxHelper instead of HtmlHelper.

Related

Reference DropDownList selected value from enclosing Form

I'm just getting started with MVC5 (from WebForms), and dropdownlist bindings are giving me some fits.
I'd like to get this working using a GET request back to the page, with a selected value parameter. I'm hopeful that I can specify the route arguments in the form itself, so I'd like to reference the DDL's SelectedValue.
<p>
#using (Html.BeginForm("Index", "Profile", FormMethod.Get, new { id = WHATDOIPUTHERE} )) {
#Html.AntiForgeryToken()
#Html.DropDownList("ApplicationID", new SelectList(ViewBag.ApplicationList, "ApplicationID", "ApplicationName", ViewBag.SelectedApplicationId), new {onchange = "this.form.submit();"})
}
</p>
I can make it work with a POST form, but that requires a second controller method so I end up with
public ActionResult Index(long? id) {
ConfigManager config = new ConfigManager();
//handle application. default to the first application returned if none is supplied.
ViewBag.ApplicationList = config.GetApplications().ToList();
if (id != null) {
ViewBag.SelectedApplicationId = (long)id;
}
else {
ViewBag.SelectedApplicationId = ViewBag.ApplicationList[0].ApplicationID; //just a safe default, if no param provided.
}
//handle profile list.
List<ProfileViewModel> ps = new List<ProfileViewModel>();
ps = (from p in config.GetProfilesByApp((long)ViewBag.SelectedApplicationId) select new ProfileViewModel(p)).ToList();
return View(ps);
}
//POST: Profile
//read the form post result, and recall Index, passing in the ID.
[HttpPost]
public ActionResult index(FormCollection collection) {
return RedirectToAction("Index", "Profile", new {id = collection["ApplicationId"]});
}
It would be really nice to get rid of the POST method, since this View only ever lists child entities.
What do you think?
You can update your GET action method parameter name to be same as your dropdown name.
I also made some small changes to avoid possible null reference exceptions.
public ActionResult Index(long? ApplicationID) {
var config = new ConfigManager();
var applicationList = config.GetApplications().ToList();
ViewBag.ApplicationList = applicationList ;
if (ApplicationID!= null) {
ViewBag.SelectedApplicationId = ApplicationID.Value;
}
else
{
if(applicationList.Any())
{
ViewBag.SelectedApplicationId = applicationList[0].ApplicationID;
}
}
var ps = new List<ProfileViewModel>();
ps = (from p in config.GetProfilesByApp((long)ViewBag.SelectedApplicationId)
select new ProfileViewModel(p)).ToList();
return View(ps);
}

How to update parent view after submitting a form through a partial view?

I have a view which when a teacher is logged in lists the complete details of a student , it also lists the tasks given to the student by the teacher logged in. If the teacher wants to create a new task for the student he clicks the create new link which in turns make an Ajax call to the controller:
#Ajax.ActionLink("Create", "CreateTask", "Task", new { id = Model.StudentId },
new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "create-div"
}, new { #class = "btn btn-default" })
which returns a partial view
[HttpGet]
public ActionResult CreateTask(int ?id)
{
//........
return PartialView("PartialViews/Task/_CreateTaskPartial");
}
In the partial view I am using Ajax.BeginForm to submit the data to create the actual task as follows
#using (Ajax.BeginForm("CreateTask", "Task",new AjaxOptions { UpdateTargetId = "create-div", InsertionMode = InsertionMode.Replace }))
{
// Form data
}
and finally in the CreateTask controller I create the task
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="TaskId")] Task #task)
{
if (ModelState.IsValid)
{
db.Tasks.Add(#task);
db.SaveChanges();
// If everything is successfull return empty
return new EmptyResult();
}
// If model errors send the view back
return PartialView("PartialViews/Task/_CreateTaskPartial", #task);
}
It creates the new task successfully but it does not update the main view which lists the details of a student and a list of created tasks. I have to refresh the page to see the last task added.
How can I make it possible so that when a 6th task is added via partial view, on success it updates the parent view and lists the 6th task also ?
I am not very experienced in MVC so please correct me where am I doing wrong.
I solved it, I got help from Here to solve it.
So what I did is instead of returning an EmptyResult() when the task is created I returned a JSON object
if (ModelState.IsValid)
{
db.Tasks.Add(#task);
db.SaveChanges();
// If everything is successfull return empty
//return new EmptyResult();
return Json(new { ok = true, url = Url.Action("Details","Student",new{id=#event.StudentId}) });
}
An d in the partial view which submits the form to vreate the task I added OnSuccess parameter in the AjaxOptions in the Ajax.BeginForm which calls a javascript function.
#using (Ajax.BeginForm("CreateTask", "Task",new AjaxOptions { UpdateTargetId = "create-div", InsertionMode = InsertionMode.Replace,OnSuccess = "onSuccess" }))
{
// Form data
}
And finally in the "onSuccess" function I cheked if the result is ok then redirect to the url in the result given by the controller.
var onSuccess = function doIt(result) {
if (result.ok) {
window.location.href = result.url;
}
};

Ajax.BeginForm OnFailure invoked when ModelState is InValid

I want to call "OnFailure" when ModelState is not valid in controller.
In My LoginView
#using (Ajax.BeginForm("Login", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "Login",InsertionMode = InsertionMode.Replace, OnSuccess = "Success", OnFailure = "onError" }))
{
}
In Controller
[httpPost]
public ViewResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
}
else
{
ModelState.AddModelError("login is fail")
}
return View("Login",model)
}
so i want call onSuccess Method if ModelState is valid and if it fail then call only OnError method with display all error which are in Model State.
Here's what you could do:
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
// everything went fine and we want to redirect in this case =>
// we pass the url we want to redirect to as a JSON object:
return Json(new { redirectTo = Url.Action("SomeController", "SomeAction") });
}
else
{
// there was an error => add an error message
ModelState.AddModelError("login is fail")
}
// return a partial view instead of a full vire
return PartialView("Login",model)
}
and then all you need is the Success function:
#using (Ajax.BeginForm("Login", new AjaxOptions { HttpMethod = "POST", OnSuccess = "loginAjaxSuccess" }))
{
}
in which you could test in which case you are:
function loginAjaxSuccess(result) {
if (result.redirectTo) {
// the controller action returned a JSON result => it was a successful login
// => we redirect the browser to this url
window.location.href = result.redirectTo;
} else {
// the action returned a partial view with the form containing the errors
// => we need to update the DOM:
$('#Login').html(result);
}
}
By the way if you are using unobtrusive client side validation in the case of error where you are refreshing the form you will need to manually force the parsing of the new validation rules, otherwise next time you attempt to submit the form, client validation won't work:
} else {
// the action returned a partial view with the form containing the errors
// => we need to update the DOM
$('#Login').html(result);
// Now that the DOM is updated let's refresh the unobtrusive validation rules on the form:
$('form').removeData('validator');
$('form').removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse('form');
}
When you detect the problem in the ModelState, set the StatusCode of the response object to something like 400 (You can get the code from the System.Net.HttpStatusCode class)
That will fire the onfailure method.
Si

How to return back a message after a submit

I have the following code which is not working as expected. I want to have a retrun from the controller and using alert display the value returned from the controller.
$('#change').dialog({
autoOpen: false,
width: 380,
buttons: {
"Close": function() {
$(this).dialog("close");
},
"Accept": function() {
var test = $("#ChangePasswordForm").submit();
alert(test);
}
}
});
In my controller I want to return a string
[AcceptVerbs(HttpVerbs.Post)]
public string ChangePassword(string Name)
{
var msg = "Cool!";
if (name != null)
return msg;
}
How can I do that?
Your controller needs to return a type that derives from an ActionResult.
If you want to display a simple confirmation message you can add it to the ViewData bag like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ChangePassword(string name)
{
if (!string.IsNullOrEmpty(name))
{
ViewData["msg"] = "Cool";
}
return View();
}
Then, in your view, check for the presence of the value, and display it if it's there:
<% if(ViewData["msg"] != null) { %>
<script type="text/javascript">alert('<%= ViewData["msg"].ToString() %>')</script>
<%} %>
First of all, im assuming you are using an ajax form for this. I also assume you have a or something for putting your text into. All you have to do is set the UpdateTargetId to point at the id of the element you want to update with the text
<%using (Ajax.Form("ChangePasswordForm", new AjaxOptions { UpdateTargetId = "result" })) %>
.
[HttpPost]
public ContentResult ChangePassword(string s)
{
var msg = "Cool!";
if ( s != null ? return Content(msg, "text/plain") : return Content("An error has occured", "text/plain") );
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ChangePassword(string Name)
{
var msg = "Cool!";
if (name != null)
{
return Content(msg, "text/plain");
}
else
{
return Content("Error...", "text/plain");
}
}
Don't submit the form as that will perform a postback and cause the dialog to be removed.
Instead perform an AJAX post to the Controller Action and return a JsonResult containing the data.
Hook into the success callback from the Ajax request, and call alert passing the data from the Json object.
You'll probably wan't to use a loading mask after clicking submit so the user knows something is going on.

ASP.NET MVC: Server Validation & Keeping URL paramters when returning the view

I currently have the following code for the POST to edit a customer note.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditNote(Note note)
{
if (ValidateNote(note))
{
_customerRepository.Save(note);
return RedirectToAction("Notes", "Customers", new { id = note.CustomerID.ToString() });
}
else
{
var _customer = _customerRepository.GetCustomer(new Customer() { CustomerID = Convert.ToInt32(note.CustomerID) });
var _notePriorities = _customerRepository.GetNotePriorities(new Paging(), new NotePriority() { NotePriorityActive = true });
IEnumerable<SelectListItem> _selectNotePriorities = from c in _notePriorities
select new SelectListItem
{
Text = c.NotePriorityName,
Value = c.NotePriorityID.ToString()
};
var viewState = new GenericViewState
{
Customer = _customer,
SelectNotePriorities = _selectNotePriorities
};
return View(viewState);
}
}
If Validation fails, I want it to render the EditNote view again but preserve the url parameters (NoteID and CustomerID) for something like this: "http://localhost:63137/Customers/EditNote/?NoteID=7&CustomerID=28"
Any ideas on how to accomplish this?
Thanks!
This action is hit by using a post. Wouldn't you want the params to come through as part of the form rather than in the url?
If you do want it, I suppose you could do a RedirectToAction to the edit GET action which contains the noteId and customerId. This would effectively make your action look like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditNote(Note note)
{
if (ValidateNote(note))
{
_customerRepository.Save(note);
return RedirectToAction("Notes", "Customers", new { id = note.CustomerID.ToString() });
}
//It's failed, so do a redirect to action. The EditNote action here would point to the original edit note url.
return RedirectToAction("EditNote", "Customers", new { id = note.CustomerID.ToString() });
}
The benefit of this is that you've removed the need to duplicate your code that gets the customer, notes and wotnot. The downside (although I can't see where it does it here) is that you're not returning validation failures.

Resources