I use ASP.NET Core 6 MVC and Entity Framework 6.0.11 and I have trouble when deleting data from SQL Server.
When I click delete button, it makes the deletePage show 0 values, when I back to the list the data I just deleted, it does not disappear (see screenshot).
My controller:
public IActionResult deletePackage (long ID)
{
ForDeletePackage = LQHVContext.Packages.Where(s => s.PackagesId == ID).FirstOrDefault();
if (ForDeletePackage == null)
{
return NotFound();
}
return View(ForDeletePackage);
}
[HttpPost]
public IActionResult Delete(long ID)
{
Package package = new Package() { PackagesId = ID };
LQHVContext.Packages.Attach(package);
LQHVContext.Packages.Remove(package);
if (LQHVContext.SaveChanges() == 1)
{
//redirect to package list
return RedirectToAction("packageList", "Packages");
}
return View("deletePackage", package);
}
My razor page:
<form asp-action="Delete">
<input type="submit" value="Delete" class="btn btn-danger" /> |
<a asp-action="listPackage">Back to List</a>
</form>
Screenshots:
My ConfirmDelete page
After I click delete btn
when I back to List, the data still there
I doubt HTML forms can do a DELETE HTTP operation against our API. The only two options are POST and GET
See this question as well Should PUT and DELETE be used in forms?
Related
I have a cshtml view, for which I am sending a viewmodel. That viewmodel consist of two list of albums (music albums). I then ask the user to check up to 3 of these albums (a checkbox next to the title) to vote for his favorite music. I use javascript to ensure he doesn't check anymore than 3 (The security is a detail right now, I'm more concerned about getting it to work, but I'm open to suggestion if people have a better solution).
Since all albums are displayed in a table, I would love to send back to the controller through the submit button, the same model after updating it.
Basically, one of the list contain the current vote the user has made before loading the page (can be empty), and the second one should be empty until sent back to the controller containing the list of votes that are currently selected. I then use these two lists to compare them and update the database, removing the votes he removed, and adding the vote he added.
But I am unable to create a proper form to return these informations as I am not used to forms.
I tried to put the whole list in a form, but it didn't work. My reserach when I look for "sending model back to controller" usually do just that and get it to work.
View model
public class CategoryVotesUserViewModels
{
public CategoryVoteViewModels categoryVoteViewModels;
public List<int> listVotesEntry = new List<int>();
public List<int> listVotesOutput = new List<int>();
}
Relevant CSHTML and javascript
#section Header{
<script>
var MAX_VOTES = 3;
function checkNumberVotes($this) {
console.log($("input[name='listVoteOutput']:checked"));
if ($("input[name='listVoteOutput']:checked").length > MAX_VOTES) {
$this.checked = false;
}
}
</script>
}
#using (Html.BeginForm("VoteInCategory", "Votes", new { SearchModel = Model }, FormMethod.Post))
{
<ul>
#foreach (var av in Model.categoryVoteViewModels.listVotes)
{
<li>
#av.album.Title | #av.votes |
<input type="checkbox"
name="listVoteOutput"
value=#av.album.ID
onclick="checkNumberVotes(this)"
#if (Model.listVotesEntry.Contains(av.album.ID))
{ <text> checked </text> } />
</li>
}
</ul>
<div class="form-group text-center">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
}
Controller
[HttpPost]
public ActionResult VoteInCategory(CategoryVotesUserViewModels categoryVotesUserViewModels)
{
if (ModelState.IsValid)
{
List<int> toAdd = categoryVotesUserViewModels.listVotesOutput.Except(categoryVotesUserViewModels.listVotesEntry).ToList();
List<int> toRemove = categoryVotesUserViewModels.listVotesEntry.Except(categoryVotesUserViewModels.listVotesOutput).ToList();
VoteService.updateVoteUserCategory(User.Identity.GetUserId(), toRemove, toAdd, categoryVotesUserViewModels.categoryVoteViewModels.categoryID);
//TODO Redirect to success
return RedirectToAction("Index", "Home");
}
return View(categoryVotesUserViewModels);
}
If the user already had voted, all album whose ID is in "ListVotesEntry" should begin checked. If the user hasn't voted, or voted for nothing previously, "ListVotesEntry" should be empty.
When the User press the submit button, if an album is checked, the album's id should be added to the "ListVotesOutput" list. Also, both "ListVotesEntry" and "ListVotesOutput" should be sent back to the controller. The list with the names of the albums and their titles/ID is no longer necessary for the rest of the treatment
Found the solution. The problem was that my model needed to use "{get; set;}" on its attributes, otherwise the binding doesn't work, which mean that it send back an empty model.
I have a problem with a form submit in Angular / .net Core.
I have a form, where the user can submit changes. The submit does a post on the .net core background. After that, the form is resetted.
So far so good, but after that it doesn't post anymore.
The problem seems to be with the form reset. If i exlude it, a second submit would work. Here is my (sample) code:
<form #frm="ngForm" id="frm" (ngSubmit)="onSubmit(frm.value, frm); frm.reset();">
<input [(ngModel)]="selectedItem" name="selectedItem" type="text" />
<button type="submit" class="mdc-button mdc-button--raised">
<span class="mdc-button__label"><i class="material-icons">done</i></span>
</button>
</form>
onSubmit(formData, form: NgForm) {
this.service.SetItem(formData, this.selectedItemTyp).subscribe(data => {
this.reload(id);
});
}
SetItem(param: object, table: string): Observable<any> {
var data = {
Item: param["selectedItem"]
};
return this.http.post('/api/item/SetItem', data).pipe(
catchError(
this.handleError('SetItem', [])
)
);
}
[HttpPost]
public IActionResult SetItem([FromBody]StatusBody parameter)
{
try
{
db.SetItem(parameter.Item);
db.SaveChanges();
return Ok("");
}
catch (Exception ex)
{
return Ok(ex.Message);
}
}
If i remove frm.reset(); in the component html, it works as expected.
The model in the server side StatusBody ,you need to send that model object correctly , otherwise it's return 400.
I found the problem, it was a parameter that was null after the first submit...
Thanks to all.
I have Get and Post partial Action. Get take me a list of image which I have in ma app.
[HttpGet]
public PartialViewResult ViewImageFileList()
{
IEnumerable<string> allImages = Directory.EnumerateFiles(Server.MapPath("~/Images/NBAlogoImg/"));
return PartialView(allImages);
}
Post delete image which I extra.
[HttpPost]
public PartialViewResult ViewImageFileList(string imageNameType)
{
var fileToDeletePath = Path.Combine(Server.MapPath("~/Images/NBAlogoImg/"), imageNameType);
if (System.IO.File.Exists(fileToDeletePath))
{
fileOperations.Delete(fileToDeletePath);
}
return PartialView();
}
My .chhtml of my partial view
#model IEnumerable<string>
<div class="name-block-style">
Логотипы которые имеются
</div>
<div id=team-logo-wrapper-images>
<ul>
#foreach (var fullPath in Model)
{
var fileName = Path.GetFileName(fullPath);
<li>
<div class="box-name-image">
<p class="image-name-type">#fileName</p>
<img src="#Url.Content(string.Format("~/Images/NBAlogoImg/{0}", fileName))"
class="logo-images" alt="Логотип команды"
title="Логотип команды" />
</div>
</li>
}
</ul>
<div id="delete-image-form" class="form-group">
#using (Ajax.BeginForm(
"ViewImageFileList",
"Team",
new AjaxOptions() { HttpMethod = "POST", OnComplete = "reloadPage()" }))
{
<label>Введите имя с указание типа изображения</label>
<input type="text" class="form-group" name="imageNameType" id="imageNameType" />
<input type="submit" value="Удалить" class="btn btn-primary" />
}
</div>
<script>
function reloadPage() {
location.reload();
}
</script>
My problem is Null references when I write the deleting image and submit it(i do it by ajax). I have this error Null reference but when I click to continue, the image deleted and my script to reload page work.
I want to understand why I take the null and how I can fix it, because it stops my app always when I delete an image.
The problem is that when you POST after you delete the image you don't populate the model of the partial view, as you do correctly in ViewImageFileList. This has a result when the View Engine try to build the view that you would send after the POST to the client, to get a null reference exception when try to perform the foreach on a null reference.
That being said, the thing you need is to pass to the PartialView all the images. So just add before the return statement in the action method you POST this:
var allImages = Directory.EnumerateFiles(Server.MapPath("~/Images/NBAlogoImg/"));
return PatialView(allImages);
When you browsing images you return view with model passed
return PartialView(allImages); //allImages is a model
But when you deleting images you return view without any model
return PartialView(); //need to pass a model
So after deleting you would like to redirect to ViewImageFileList to browse
all images
[HttpPost]
public RedirectToRouteResult ViewImageFileList(string imageNameType)
{
var fileToDeletePath = Path.Combine(Server.MapPath("~/Images/NBAlogoImg/"), imageNameType);
if (System.IO.File.Exists(fileToDeletePath))
{
fileOperations.Delete(fileToDeletePath);
}
return RedirectToAction("ViewImageFileList");
}
or retrieve images in delete action once again and pass the list to view
[HttpPost]
public PartialViewResult ViewImageFileList(string imageNameType)
{
var fileToDeletePath = Path.Combine(Server.MapPath("~/Images/NBAlogoImg/"), imageNameType);
if (System.IO.File.Exists(fileToDeletePath))
{
fileOperations.Delete(fileToDeletePath);
}
IEnumerable<string> allImages = Directory.EnumerateFiles(Server.MapPath("~/Images/NBAlogoImg/"));
return PartialView(allImages);
}
Good day,
I have a button
<a class="btn btn-primary btn-large" href="/servicios/ChangeFieldToFalse?Id=4">change field to false</a>
and this in my backend
public ActionResult ChangeFieldToFalse(Guid Id)
{
var userId = User.Identity.GetUserId();
var result= _myclass.changeFieldToFalse(servicioId, userId);
return .....
}
Is it possible to avoid refreshing the page without using ajax? if so, how would I do it? I mean, I click on the button, a field in a table is changed to false.
Thank you .
Hi I AM using Database first approach in my MVC project. I have an action where I am calling Stored procedure when user clicks on Accept terms.
Here as soon as i calling this stored procedure, in my table it is storing current date and making termsaccepted field from false to true. It is working fine. I have condition like only when user accepted terms they can redirect to Default page. But even after calling stored procedure and updating date it is not redirecting to Default page.
And what I observed is, if i close and open my solution, then it is taking latest value stored in database and then it is redirecting to page which i need.
So how can i redirect to page as soon as value updated in my database without restarting Visual Studio ?
My Action :
public ActionResult Termspage()
{
TermsEntities updateterms = new TermsEntities();
var ID = Session["userID"];
if (ID != null)
{
updateterms.usp_UpdateUserTerms(Convert.ToInt32(ID), true);
updateterms.SaveChanges();
}
return View();
}
My View :
<body>
<div>
#using (Html.BeginForm("DefaultPage", "Home", FormMethod.Post, new { id = "frmIndex" }))
{
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td>
<input type="submit" value="Accept Terms & Condition" />
</td>
</tr>
</table>
}
</div>
</body>
Here it's not redirecting to Defaultpage action even after details are updated in my database. But when i reopen my solution then it is redirecting to Defaultpage.
Update :
I tried to use redirecttoAction but when I use this I am getting This webpage has redirect loop error
Try PostRedirectGet method in MVC using RedirectToAction
public ActionResult Termspage()
{
TermsEntities updateterms = new TermsEntities();
var ID = Session["userID"];
if (ID != null)
{
updateterms.usp_UpdateUserTerms(Convert.ToInt32(ID), true);
updateterms.SaveChanges();
return RedirectToAction("Detail", new {id=ID})
}
}
Then
public ActionResult Detail(int id)
{
// get record
return View();
}