Hi I am new to MVC and I have the below senario
VIEW:
step3.cshtml is my view
This has data binded to step3.js(using knockout)
$.post("/Step/Step4", { "some":some_data }, function (data) {
}, 'JSON');
CONTROLLER:
[HttpPost]
public ActionResult Step4(model foo)
{
//save this data to the database and return a view
using (DBContext dbContext = new DBContext())
{
dbContext.Table.Add(foo);
dbContext.SaveChanges();
}
return View(foo);
}
public ActionResult Step4()
{
//get this view with the model
}
I am able to see that the view Step4.cshtml is able get the property values from model but.
I see that my View Step4.cshtml is a response header from the post how do I render this in the browser.
Is this the right approach??
So is it that an HTML form post can return a view and replace the whole content and AJAX cannot do that except for the partial view update?
When you call $.post, you are making a jQuery ajax request with a POST method. That data is given back to you in the success method. If you are returning the view, then you will have to manually replace the html in your document with that response.
Normally, when you use ajax like this, you would return a PartialView to update a section of your page, not your whole page. You might want to see if you can return a partial and update a div.
You can also do that by using an Ajax.ActionLink, and in the AjaxOptions, specify the id of the element you want to update when the response is returned, and the InsertionMode, which should be set to Replace. And you won't have to worry about replacing the content yourself.
Please see this stackoverflow question, which may help you: How To Use Ajax.ActionLink
Related
I am using jquery Datatables Editor and can't quite seem to figure out the set-up of how the inline editing should go. Meaning my Controller code reads like this
[HttpGet]
[Route("api/tta")]
public JsonResult Index()
{
var ListData = _context.TTA.FromSqlRaw("Select * from dbo.Test").ToList();
return Json(new { Data = ListData });
}
which when I launch my asp.net core MVC append load the page the data loads exactly as expected. However, when I try the inline edit and press the submit button for the edit, I get this error in the dev console
jquery-3.3.1.js:9600 POST https://localhost:44343/api/tta 405 (Method Not Allowed)
Now from my understanding it seems that the issue is that a POST is being attempted on an API that is only set up to make a GET request. Which leads me to my question of what is the proper way to set this up so that the data will be submitted to the database successfully?
ASP.Net Core & MVC & Microsoft SQL Server if needed here is a link to the inline edit feature of DataTables https://editor.datatables.net/examples/inline-editing/submitButton.html
You need to create an method that accept POST request and recieve your data. Example:
[HttpPost]
[Route("api/tta")]
public JsonResult Post(YourType yourParameter)
{
var result = MethodThatUpdateYourData(yourParameter);
return Json(result);
}
From looking at the code given, your api/tta method allows just [HttpGet]. Simply add a new method with [HttpPost] which you can call to submit the data
I am creating a web page using ASP.Net WebAPi, MVC and Knockout.
I have a normal MVC controller that loads the pages when I need them:
[Authorize]
public class AdminController : Controller
{
public ActionResult Clients()
{
return View();
}
public ActionResult ClientEdit(int? Id)
{
return View();
}
}
And once the page is loaded, my Knockout model takes care of the loading of the data. So, the 'Clients' controller simply loads a list of all clients. When on that screen, a user can click 'Edit' next to a client, and the page is navigated to the 'ClientEdit' controller, which takes an id.
So, my knockout click event looks like this in my knockout view model:
self.EditClick = function () {
if (this.ClientId && typeof this.ClientId !== 'undefined') {
window.location.href = "/Admin/ClientEdit/" + this.ClientId;
}
else
window.location.href = "/Admin/ClientEdit/";
}
(It handles the 'Create New' button and the edit button, hence the 'if')
Once I redirect, the MVC controller loads the page, and the URL is:
http://localhost:49389/Admin/ClientEdit/1
I then load the knockout model, and would like to make an API call to get the data...
After my page loads, I want to bind the view model to the page. Here's my view model at the moment:
function AdminClientEditor() {
var self = this;
self.Name = ko.observable("");
self.ContactName = ko.observable("");
ko.applyBindings(new AdminClientEditor(), $("#clienteditor")[0]);
So, I will create a $.get method that calls a webAPI method that will return me data based on the id. I just need to get the ID somehow.
But, how do I get the Id (In this case, '1', from the URL?
And, is this the right way to achieve what I am trying to do?
You can pass the id value to view via viewbag.
public ActionResult ClientEdit(int? Id)
{
ViewBag.ClientId=id;
return View();
}
and in the view's script section
var clientId="#ViewBag.ClientId";
alert(clientId);
// use this
If your javascript code which accesses this id value is inside a separate external js file, you may set this value to a js variable in your view and access it in your js file. Make sure to use namespacing to avoid global variable overwriting value issues.
So in your view
<script>
var myApp = myApp || {};
myApp.ClientId= "#ViewBag.ClientId";
</script>
<script src="~/Scripts/PageSpecificExternalJsFile.js"></script>
And in the PageSpecificExternalJsFile.js file,
var clientId=myApp.ClientId;
//use this as needed
I'm not sure if this is the best way, but you can get the ID from the URL by using JS:
var id = GetID();
function GetID() {
var href = location.href;
var results = href.split("/");
return results[results.length - 1];
}
I've come up with this solution which works, but I am unsure if it's the best way. It seems pretty good.
I created a MVC ViewModel class in my application code, called 'GenericParameteModel', which at the moment, has a single parameter, "Id".
I then modified my page loading MVC method:
public ActionResult ClientEdit(int? Id)
{
var mv = new GenericParameteModel { Id = Id };
return View(mv);
}
On my View page, I added the model 'GenericParameteModel' to the View.
I created a hidden field, called 'ClientId' on the view.
<input type="hidden" id="clientId" value="#model.Id">
Then, within my knockout view model, I check if $("#clientId").val() has a value. If so, I do the $.get call, using that value, and populate my view model.
In doing so, all my initial page loads from MVC will have the ability to you the GenericParameteModel, and it will be a pattern for other pages. As it's a model, I can add new fields as my application requires.
This seems to work well. I'm unsure if this is an acceptable way as I am new to this (MVC to load views and the Knockout/WebApi to get the data after loading). But it seems neat and manageable.
I am trying to make my web application like a desktop application.
I am also not using any _LayoutPage and #RenderBody().
I have a ContentPage as MasterPage and a tag named main
I am using ajax get method to render my views or partial views like this:
$.get(url).done(function (result) {
$("main").html(result);
});
I managed to inject my script and css files with javascript functions.
And now I want to pass some specific datas without using javascript functions.
It can be via using ViewBag, I guess.
I want to pass that data from my partialView:
ViewBag.BodyClass = "signup-page";
to my MainPage like this:
<body class="#ViewBag.BodyClass">
How can I do that?
A little note: Please ignore that I am a newbie and my low reputation
If you have a script manager ($.get) that calls your server to get the views and partial views, no problem.
When you request a URL, normally MVC calls a Controller and Action. In that action you can return content, view, partial view, file and so on...
You can create a new instance of a class model and pass to your partial view.
public ActionResult Index(string parameter1, string parameter2)
{
var model = new Models.ModelTest();
model.BodyClass = "some class";
return PartialView("_Page", model);
}
You will call some like this:
$.get("http://localhost/app/getviews?id=3422¶meter1=test¶meter2=foo")
In your view or partial view:
#model YourApp.Models.ModelTest
<body class="#Model.BodyClass">
I use that all the time.
I wrote that code on my partialView. It adds a class at ContentPage's body tag
$("body").addClass("signup-page");
So I have an HttpPost in my controller that requires an object from my model. It then returns an HttpStatusCodeResult depending on success of the action. On my view, I want to run some basic javascript based on the status code result instead of redirecting to a new page. I would simply do this with AJAX but I need to send the object with a form. How would I go about doing this?
You can serialize your form and send it via ajax. Your model binding will work fine. Send a response which your client side js code can read and execute your CUSTOM functions then.
Example, You might have a create view with a form like this
#model CreateCustomerVM
#using(Html.Beginform())
{
#Html.TextBoxFor(s=>s.Name)
<input type="submit" id="btnSubmit" />
}
and the script to handle the form posting
$(function(){
$("#btnSubmit").click(function(e){
e.preventDefault();
var frm=$(this).closest("form");
$.post(frm.attr("action"),frm.serialize(),function(res){
//do something with res here'
// if(res.Success)
// {
// alert(res.Message)
// }
});
});
});
So your HttpPost action method should read the posted form, Do whatever it needs to do and send a response back, like this
[HttpPost]
public ActionResult Create(CreateCustomerVM model)
{
// to do : Read from model and save
// someService.Save(model)
return Json(new { Success = true, Message="Saved successfully"});
}
I'm trying to update the Model with a background Ajax Post, below is my existing code
Javascript (Jquery)
var url = '#Url.Action("UpdateValue", "MyController")';
$.post(url, $('form').serialize(), function (view) {
//...
});
Controller
[HttpPost]
public ActionResult UpdateValue(MyViewModel model)
{
model.FileName = "NewValue";
return Json(new { success = true });
}
This code posts the existing model to controller and then I'm updating the field FileName, but this does not seem to retain the updated value ("NewValue"). How to make it update the existing model with new value?
Setting model.FileName in the action doesn't do anything to the UI or the database. It depends on what you are trying to update, but if you are trying to update the UI, you would need to push the model back down to the client, and then reload the UI via client-JavaScript (since you are doing an AJAX post with JQuery).
How about sending back the updated model:
[HttpPost]
public ActionResult UpdateValue(MyViewModel model)
{
model.FileName = "NewValue";
return Json(model);
}
Then in your $.post you can read the response and update your field.
As Brain Mains commented, you can't persist the model. Model is just nice way of accessing POSTed values.
Let's assume you are posting more values than FileName. So instead of doing this:
Request.Form["FileName"];
Request.Form["Id"];
Request.Form["Size"];
You just do this:
model.FileName
model.Id
model.Size
It's a lot cleaner and nicer to work with.
So If you follow the process of posting data:
User clicks a button > data is submitted via ajax > arrives to the asp.net engine > engine binds submitted data to the model > model is passed to controller > controller returns a result (and in this moment ... hackemate! ... the model is gone)