AngularJs $http.post does not render new View - c#

I'm having this AngularJs http.post-function. In my view I have a list of Id:s. And when I click on any of these Id:s this function gets hit.
$scope.GoToSinglePost= function (id) {
console.log(id);
if (confirm("Go to blogPost with " + id + " ?")) {
$http.post("/Home/SingleBlogPost", { postId: id });
}
};
Everything works fine here and the post gets me to my mvc c# actionresult witch is this one below:
public ActionResult SingleBlogPost(int? postId)
{
var singlePost = _repo.GetSinglePost(postId);
var viewModel = new SingleBlogPostViewModel()
{
Post = singlePost
};
return View(viewModel);
}
In this ActionResult the postId i've sent from my angularPost gets in to the parameter int? postId
And the actionResult starts to render and it's if I debug it, I can see that it will go in to its view (SingleBlogPost.cshtml)
But what happens if I watch it in my browser, everything stays the same. I'm still in the same view where I was from the beginning. Why doesn't my SingleBlogPost Actionresult-view renders in the browser? Why I'm I still on the same page even though the SingleBlogPost-method gets hit and goes thuogh it's view when I debug?
//Thanks

try adding a success or then once the operation is complete to perform further actions there, something like:
$http.post("/Home/SingleBlogPost", { postId: id }).success(function(data) {
//data is your response from server to the request;
//do something with data here, like changing to correct view;
});

Related

ASP.NET Core MVC: Get values from Ajax, send to new View

This is similar to a previous issue that was resolved earlier. In this case, instead of rendering a table in the same view, I'd like to take the data retrieved and push to a new view:
Populate child area paths in a multiselect dropdown list
Select some of the items in the dropdown list
Take the selected items (as area path children) send back to controller
From controller use area paths as parameters to a method retrieving work items
Take workitem list and populate list in new view
Here is my view script
function GetSelectedAreaPathChildren3() {
alert("TEST1");
var selectedAreaPathItems = '';
$("#AreaPathMultiSelectDropdownList :selected").each(function () {
selectedAreaPathItems += this.value + ";";
});
var selectedIterationPathItems = '';
$("#IterationPathMultiSelectDropdownList :selected").each(function () {
selectedIterationPathItems += this.value + ";";
});
console.log(selectedAreaPathItems);
$.ajax({
url: '#Url.Action("WorkItemTable", "PbcAzureDevOps")',
type: "POST",
data: { selectedAreaPathItems, selectedIterationPathItems },
success: function () {
alert("BLAH!");
}
});
}
Here is my controller method
public async Task<IActionResult> WorkItemTable(string selectedAreaPathItems, string selectedIterationPathItems)
{
//Get the retrieved work items
List<WorkItemInfo> retrievedWorkItems =
await GetAllSelectedWorkItems(selectedAreaPathItems, selectedIterationPathItems);
return View(retrievedWorkItems);
}
Expected result:
retrievedWorkItems is populated and sent to view ("WorkItemTable") -- after sending to view, "WorkItemTable is shown on screen
Actual result:
retrievedWorkItems is populated and sent to view ("WorkItemTable") -- after sending to view, "WorkItemTable is NOT SHOWN (i.e. WorkItemTable does not pop up)
I recognize from my research that I can't get the view to show up from the script and have also tried adding the following to the view:
#using (Html.BeginForm("WorkItemTable", "PbcAzureDevOps", FormMethod.Post))
{
}
Can anyone help me to get the WorkItemTable to render... I can already see the data in the foreach part of the view, it just doesn't show.
So I figured a workaround... instead of pulling the selections from the dropdownlists using Ajax, I pulled the data from the dropdown via IFormCollection:
public async Task<IActionResult> WorkItemTable(IFormCollection collection)
{
List<string> selectedAreaPathItems = collection["apchildrenDropDown"].ToList();
List<string> selectedIterationPathItems = collection["ipchildrenDropDown"].ToList();
//Get the retrieved work items
List<WorkItemInfo> retrievedWorkItems =
await GetAllSelectedWorkItems(selectedAreaPathItems, selectedIterationPathItems);
return View(retrievedWorkItems);
}

Why are form field entries disappearing after submitting?

I have form that a user submits. For some reason, in our production environment when they click submit, the form is cleared and they lose all that they filled in when they click submit. I've been lost on this for awhile so any input would really help.
I've tried on multiple browsers and this occurs on each one (Chrome, Safari).
The first action creates the view model for the form, the second one takes that data/model and submits an application:
[Authorize(Roles = "Applicant")]
public IActionResult Application()
{
var vm = _applicantManager.GetApplicationViewModel(CurrentUser.UserName);
return View(vm);
}
[HttpPost]
//[ValidateAntiForgeryToken]
[Authorize(Roles = "Applicant")]
public IActionResult Application(ApplicationViewModel model)
{
var saved = false;
model = _applicantManager.RebuildApplicationViewModel(model);
if (ModelState.IsValid)
{
saved = _applicantManager.SubmitApplication(model, CurrentUser.UserName);
return RedirectToAction("Index");
}
return View(model);
}
I'm thinking if I remove the ValidateAntiForgeryToken that maybe this would solve issue, but am not sure.
Is it possible that the first action needs a route? On testing, it goes to the action with the HttpPost attribute when I click submit on my local environment.
Note: This is a problem on the production server, this does not occur on the local. This leads me to believe that may a possible IIS setting that needs changed?
JavaScript on the Page:
<script>
require(['jquery', 'jqueryui'], function($, jqueryui) {
$(function() {
$("#preHealthAreaDiv input:radio").click(function () {
var selectedVal = $("#preHealthAreaDiv input:radio:checked").val();
if (selectedVal == "Yes") {
$("#preHealthAreaDetail").show();
}
else {
$("#preHealthAreaDetail").hide();
}
})
});
});
</script>

asp.net core 2 razor pages route with id

There are two page one is Edit page and the other is Main Detail page which is combined data of some entities
In edit page :
after edit done and I posted the data to API as below
public async Task<IActionResult> OnPostAsync(Guid id)
{
ManufacturerAuthorizedPerson.Id = id;
ManufacturerAuthorizedPerson.ManufacturerId = GetManufacturerId(id);
if (!ModelState.IsValid)
{
await OnGetAsync(id);
return Page();
}
HttpResponseMessage = await httpSystemApi.PutAsync("ManufacturerAuthorizedPersons", ManufacturerAuthorizedPerson);
if (HttpResponseMessage.IsSuccessStatusCode)
{
return RedirectToPage("../Detail", ManufacturerAuthorizedPerson.ManufacturerId);
}
else
{
await OnGetAsync(id);
return Page();
}
}
The ID in OnPostMethod(Guid id) is the value of edited entity. I am using the value and get the other one to use in route as below to get detail page.
ManufacturerAuthorizedPerson.ManufacturerId = GetManufacturerId(id);
but on the detail page the value coming from route ID that I sent from Edit pages post method like below
return RedirectToPage("../Detail", ManufacturerAuthorizedPerson.ManufacturerId);
do not show up as route URL.Instead of ID is beeing same as I wa sent to Edit Page.
Little bit confused.
Need help please.
Suddenly I have found simpe solution to this problem. You should type:
return RedirectToPage("../Detail", new {id = ManufacturerAuthorizedPerson.ManufacturerId});

Viewmodel binding for Edit View

Having some trouble with the "GET" part of the Edit View, and can't really find anything online. So far, this is my POST section:
[HttpPost]
public ActionResult Edit(ContactsEditViewModel viewModel)
{
if (ModelState.IsValid)
{
var Contacts = TheContactContext.tblContacts.Find(viewModel.ID);
Contacts.Company = viewModel.Company;
Contacts.Contact = viewModel.Contact;
Contacts.Contact2 = viewModel.Contact2;
Contacts.Email1 = viewModel.Email1;
Contacts.Email2 = viewModel.Email2;
Contacts.IsSupplier = viewModel.IsSupplier;
Contacts.Telephone = viewModel.Telephone;
Contacts.Link = viewModel.Website;
Contacts.Notes = viewModel.Notes;
TheContactContext.SaveChanges();
return RedirectToAction("~/Contacts/Index");
}
return View(viewModel);
}
I've only ever done this using EntityFramework and letting it scaffold everything, so it's the first time using Viewmodels to do it personally.
Any help in whether my POST action is correct, and some guidance on the GET action would be appreciated :)
I believe you're on the right track with POST. GET is much more simplier:
public ActionResult Create()
{
return View(new ContactsCreateViewModel() { ... your initial settings, may be contained within constructor of view model directly ... });
}
The GET request requests server to provide empty form, which is filled by user, and filled data are sent back via POST, and processed within your provided function.
EDIT
If you are talking about Edit, then it is similar with one more step:
public ActionResult Edit(int id)
{
var data_model = TheContactContext.tblContacts.Get(id); // get model probably from database
var view_model = new ContactsCreateViewModel() {
Company = data_model.Company,
...
}; // copy all data into view model
return View(view_model); // and display view
}
When your page loads for a first time it sends GET request and retrieves model with collection of items from Db. After you've updated some of these items your app sends post request (most likely using Ajax) containing json data. You update your database in controller method and now it's time to refresh your page data. Simplest way is to use ajax.
$.ajax({
url: "http://" + location.host + "/CTRL/Action",
type: "POST",
data: yourdata,
}).done(function (html) {
location.reload(); (or other method to update UI)
}).fail(function (err) {
alert(err.statusText);
});
It's for client side. Server side is smth like :
lock (obj)
{
try
{
update database here...
}
catch(Exception ex)
{
return new HttpStatusCodeResult(System.Net.HttpStatusCode.ServiceUnavailable, ex.Message);
}
return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK, "Update completed");
}

Asp.Net MVC - Blank model not returning blank data

I have a form which a user can fill in x times with the data they want too. The form is posted to the following Action.
[HttpPost]
public ActionResult Manage(ProductOptionModel DataToAdd)
{
if (!ModelState.IsValid)
{
return View(DataToAdd);
}
var ProdServ = new ProductService();
if (DataToAdd.ID != 0)
{
//Edit Mode.
DataToAdd = ProdServ.EditProductOption(DataToAdd);
ViewData["Message"] = "Option Changes Made";
}else
{
//Add
DataToAdd = ProdServ.AddProductOption(DataToAdd);
ViewData["Message"] = "New Option Added";
}
var RetModel = new ProductOptionModel() {ProductID = DataToAdd.ProductID};
return View(RetModel);
}
So at the bottom I blank the model (Leaving just the required field) and then return to the view. However the view holds the data from the previously submitted form.
Any ideas why? I have debugged the code and checked that the RetModel variable is empty.
Html helpers work this way when a view is returned on HTTP POSTs. They prefer post data over model values.
Use Post/Redirect/Get
That's why I suggest you use the Post/Redirect/Get pattern that's very well supported in Asp.net MVC. Your controller actions should redirect to some GET action after POST has successfully completed as it is in your case.
public ActionResult Process()
{
return View(new Data { Id = -1 });
}
[HttpPost]
public ActionResult Process(Data data)
{
if (!this.ModelState.IsValid)
{
return View(data);
}
new MyService().ProcessData(data);
return RedirectToAction("Process");
}
And if you display all previously entered data you can provide those in in the GET action or transfer them from POST to GET action using TempData dictionary.
This is because the build in input helpers will look at the posted data first and use those values if they exist. Then it will look at the model.

Categories