I changed some things around for an item that was requested. This required me to add a parameter to one of the controller ActionResults.
public ActionResult RejectDocument(int id = 0, string rejectReason)
{
IPACS_Version ipacs_version = db.IPACS_Version.Find(id);
ipacs_version.dateDeleted = System.DateTime.Now;
ipacs_version.deletedBy = User.Identity.Name.Split("\\".ToCharArray())[1];
db.SaveChanges();
return RedirectToAction("Approve");
}
Also this link needs to be activated from jQuery after some jQuery items finish. How do I pass this link off now?
should it be href= Document/RejectDocument?id=222&rejectReason=this is my reject reason
could I then do window.location = href; and it would call the controller and pass in the correct information?
You could use the Url helper to create the right url using the table routes rules. For sample:
window.location = '#Url.Action("RejectDocument", "YourController", new { id = 222, rejectReason = "this is my reject reason" })';
Related
I need to get the selected value of a dropdownlist when I click an ActionLink.
Here is the dropdownlist I am binding from controller.
#Html.DropDownList("resource", new SelectList(ViewBag.ResourceList, ViewBag.SelectedResource), "Resource", new { #class = "span6", #style = "width:14%; color:black;"})
And ActionLink with the function without [HttpPost]
#Html.ActionLink("Export Data", "ExportData");
I have tried from Request.Form["resource"] but it gives me null all the time
public ActionResult ExportData()
{
var req = Request.Form["resource"];
}
I just need to get the text value whatever is in the DropDownList inside my ExportData Function.
The action link basically renders an a tag, and the a tag will look something roughly like this;
Export Data
Because links issue a GET request, any parameters need to be passed via:
Export Data
Request.Form will always be empty in a get request because a POST request populates the form collection. But either way, with a GET or POST request, you can pass the data as a parameter of the action method like:
public ActionResult ExportData(string resource)
So either put a <form> around the data you want to post to the server and change the hyperlink to a button to initiate the post, or use javascript to append "?resource=VAL" to the end of the hyperlink HREF attribute, where VAL is the value from the dropdown.
EDIT: in the few scenarios I had to do this before, what I'll normally do is on the link, add a data attribute (in C# API, use data_ for data attributes):
#Html.ActionLink("Export Data", "ExportData", new { data_url = "ExportData" })
The reason why I use a data attribute is to preserve the original URL and that way I don't have to do string manipulation. Using jQuery, on resource value change, you can update the URL easily:
$("#resource").on("change", function(e) {
var val = $(this).val();
var href = $("#linkid").data("url") + "?resource=" + val;
$("#linkid").attr("href", href);
});
Anytime the dropdown changes, it updates the link url.
You should try the GetValues() method:
public ActionResult ExportData()
{
var req = Request.Form.GetValues("resource");
}
Using ASP.NET, C# and Javascript, I'm trying to dynamically get Data for the user, POST it to a controller, and return a view that changes depending on the Data.
Here's the code :
Javascript function :
function editEntry(id) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "Edit?id=" + id, true);
xmlhttp.send({ id: id });
//xmlhttp.send();
}
Controller handling post (a portion) :
[HttpPost]
public ActionResult Edit(EditEvenementiel edit)
{
var contexte = new intranetEntities1();
SqlParameter Id_viewBag = new SqlParameter("#id", edit.id);
ViewBag.edit = contexte.evenementiel
.SqlQuery("SELECT * FROM evenementiel WHERE id_evenementiel = #id", Id_viewBag);
return View();
}
when i fire the javascript, i can see the POST in the firebug console (working fine), i can see the variable getting the correct value in Visual Studio's Debugger, but the view doesn't change.
I even see the expected view (with all the treatements expected) returned in the firebug console; but my page still doesn't change.
How can i do that ?
By default, you should have 2 Actions, one that should process/get the data through a Post method and one that collects data for the View. (it's called Post/Redirect/Get - more details on wiki)
Having this in mind, you can leave your post method as :
[HttpPost]
public ActionResult Edit(int id)
{
var contexte = new intranetEntities1();
SqlParameter Id_viewBag = new SqlParameter("#id", id);
EditEvenementiel edit = contexte.evenementiel.SqlQuery("SELECT * FROM evenementiel WHERE id_evenementiel = #id", Id_viewBag);
return RedirectToAction("Edit",new { edit = edit} );
}
and create a new action which sends the data to the view.
Something like:
public ActionResult Edit(EditEvenementiel edit)
{
//logic here
return View(edit);
}
Please be aware that this is just an example, modify it according to your scenario.
As you are using Ajax (XMLHttpRequest) to fetch this data you also need to present it on your page, it wont happen automatically.
Maybe something like this?
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
alert(xmlhttp.responseText); // or put the responseText in a HTML element of your choice to do whatever you want to do
}
}
Where do you actually update anything on the page? All you do is send the request:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "Edit?id=" + id, true);
xmlhttp.send({ id: id });
But you ignore the response. The browser isn't going to know what you want to do with that response, you have to tell it. Which could be something as simple as:
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById('someElement').innerHTML = xmlhttp.responseText;
}
}
Basically, use the AJAX response (which is an HTML view?) to update the page content.
Question background:
I am implementing some basic 'shopping cart' logic to an MVC app. Currently when I click a link - denoted as 'Add To Cart' on the screen shot below this calls to an 'AddToCart' method in the 'ProductController' as shown:
Product.cshtml code:
#Html.ActionLink("Add To Cart", "AddToCart")
'AddToCart' method in the ProductController:
public void AddToCart()
{
//Logic to add item to the cart.
}
The issue:
Not an issue as such but currently when I click the 'Add To Cart' button on the ActionLink on the ProductDetail.cshtml view the page calls the 'AddToCart' method on the ProductController and gives a blank view on the page - as shown below. I want the view to stay on 'ProductDetail.cshtml' and just call the 'AddToCart' method, how do I do this?
Basically #Html.ActionLink() or <a></a> tag uses get request to locate the page. Hence whenever you clicked it, you request to your AddToCart action method in ProductController and if that action method returns null or void so a blank or empty page is shown as you experienced (because or #Html.ActionLink() get request by Default).
So if you want to add your value to cart then call AddToCart method using ajax i.e:
HTML:
#Html.ActionLink("Add To Cart", "AddToCart", null, new { id="myLink"})
Jquery or Javascript:
$("#myLink").click(function(e){
e.preventDefault();
$.ajax({
url:$(this).attr("href"), // comma here instead of semicolon
success: function(){
alert("Value Added"); // or any other indication if you want to show
}
});
});
'AddToCart' method in the ProductController:
public void AddToCart()
{
//Logic to add item to the cart.
}
Now this time when the call goes to AddToCart method it goes by using ajax hence the whole page will not redirect or change, but its an asynchronous call which execute the AddToCart action method in your ProductController and the current page will remains same. Hence the product will also added to cart and page will not change to blank.
Hope this helps.
The answer of Syed Muhammad Zeeshan is what you are looking for, however you may return an EmptyResult.
public ActionResult AddToCart()
{
//Logic to add item to the cart.
return new EmptyResult();
}
According to this it has no impact on your code ASP.Net MVC Controller Actions that return void
But maybe sometime you want to return data and then you could do something like this:
if (a)
{
return JSon(data);
}
else
{
return new EmptyResult();
}
As many people mentioned here you will need to use AJAX if your using asp.net MVC to hit a controller POST function without having to leave your view.
A good use case for this is if you want to upload a file without refreshing the page and save that on the server.
All of the
return new EmptyResult();
Wont work, they will still redirect you.
Here is how you do it, in your view have the follow form as an example:
<form enctype="multipart/form-data" id="my-form">
<p>
The CSV you want to upload:
</p>
<input type="file" class="file-upload" name="FileUpload" />
</div>
<div>
<button type="submit" class="btn btn-default" name="Submit" value="Upload">Upload</button>
</div>
</form>
Then in the JavaScript side you need to add this to your view with within Script tags.
$("#my-form").on('submit', function (event) {
event.preventDefault();
// create form data
var formData = new FormData();
//grab the file that was provided by the user
var file = $('.file-upload')[0].files[0];
// Loop through each of the selected files.
formData.append('file', file);
if (file) {
// Perform the ajax post
$.ajax({
url: '/YourController/UploadCsv',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
alert(data);
}
});
}
});
Your controller might look something like this to process this type of file:
[HttpPost]
public void UploadCsv()
{
var listOfObjects = new List<ObjectModel>();
var FileUpload = Request.Files[0]; //Uploaded file
//check we have a file
if (FileUpload.ContentLength > 0)
{
//Workout our file path
string fileName = Path.GetFileName(FileUpload.FileName);
string path = Path.Combine(Server.MapPath("~/App_Data/"), fileName);
//Try and upload
try
{
//save the file
FileUpload.SaveAs(path);
var sr = new StreamReader(FileUpload.InputStream);
string csvData = sr.ReadToEnd();
foreach (string r in csvData.Split('\n').Skip(1))
{
var row = r;
if (!string.IsNullOrEmpty(row))
{
//do something with your data
var dataArray = row.Split(',');
}
}
}
catch (Exception ex)
{
//Catch errors
//log an error
}
}
else
{
//log an error
}
}
There are many ways to accomplish what you want, but some of them require a lot more advanced knowledge of things like JavaScript than you seem aware of.
When you write ASP.NET MVC applications, you are required to have more intimate knowledge of how browsers interact with the web server. This happens over a protocol called HTTP. It's a simple protocol on the surface, but it has many subtle details that you need to understand to successfully write ASP.NET MVC apps. You also need to know more about Html, CSS, and JavaScript.
In your case, you are creating an anchor tag (<a href="..."/>), which when click upon, instructs the browser to navigate to the url in the href. That is why you get a different page.
If you don't want that, there are a number of ways change your application. The first would be, instead of using an ActionLink, you instead simply have a form and post values back to your current controller. And call your "add to cart" code from your post action method.
Another way would be have your AddToCart method look at the referrer header (again, part of that more subtle knowledge of http) and redirect back to that page after it has processed its work.
Yet another way would be to use Ajax, as suggested by Syed, in which data is sent to your controller asynchronously by the browser. This requires that you learn more about JavaScript.
Another option is to use an embedded iframe and have your "add to cart" be it's own page within that iframe. I wouldn't necessarily suggest that approach, but it's a possibility.
Controller should return ActionResult. In this case a redirect to the caller page.
using System.Web.Mvc;
using System.Web.Mvc.Html;
public ActionResult Index()
{
HtmlHelper helper = new HtmlHelper(new ViewContext(ControllerContext, new WebFormView(ControllerContext, "Index"), new ViewDataDictionary(), new TempDataDictionary(), new System.IO.StringWriter()), new ViewPage());
helper.RenderAction("Index2");
return View();
}
public void Index2(/*your arg*/)
{
//your code
}
I was struggling with this and couldn't get it working with ajax.
Eventually got a working solution by making my controller method return type ActionResult rather than void and returning a RedirectToAction() and inputting the action relating to the view I wanted to remain on when calling the controller method.
public ActionResult Method()
{
// logic
return RedirectToAction("ActionName");
}
I have a View -
#Html.TextBox("Text1","", new { style = "width:350px;" })<br />
<input type="submit" value="Pay" onclick="location.href='#Url.Action("Pay", "Test")'" />
where Pay is my action result and Test is my controller.
I would like to have Text1 value in controller.How can I achieve this with out using Form and not through ajax call?
You will have to use javascript. Start by giving your textbox an unique identifier:
#Html.TextBox("Text1", "", new { id = "text1", style = "width:350px;" }
and then in the onclick handler you could pass the value entered in the textbox to the controller action:
onclick="location.href='#Url.Action("Pay", "Test")?text=' + encodeURIComponent(document.getElementById('text1').value);"
and now your Pay controller action might look like this:
public ActionResult Pay(string text)
{
...
}
Controller expects HTTP verbs e.g. POST, GET, etc. POST requires a <form /> while GET requires query string. You could use query string to pass your values
function sendValues()
{
var value1 = document.getElementById('txtfirstname').value;
var value2 = document.getElementById('txtlastname').value;
var url = 'http://mysite.com/controllername/?firstname='+value1+'&lastname='+lastname;
location.href = url;
}
However, I don't this it's ok to expose values in query string if they are sensitive
It is possible using either Javascript/Jquery Ajax or Form.
I have a page that is rendered via an ActionResult called EntityIndex that takes int id as a parameter and loads that entity.
On this view a user can select from a dropdown other related entities and the view should reload by sending the selected ID from the dropdown to the same Action EntityIndex with the new ID.
I'm using a jQuery change event on the dropdown to navigate and reload the page:
$("#RelatedEntity").change(function () {
window.location = '#Url.Action("EntityIndex", new {id = ""})' + '/' + $(this).val();
});
This is the Action
public ActionResult EntityIndex(int id) {
... gets entity by id here ...
return View(model);
}
The action works fine when hit but the jQuery line above is failing with an error:
http://localhost:1798/Entity/EntityIndex/#Url.Action("EntityIndex", new {id = ""})/539
For some reason the window.location firing the #Url.Action is treating the action as a string and not an action to navigate to... what is wrong with the Url.Action that keeps it from behaving correctly?
Your JQuery is ever-so-slightly off. Using the default route and specifying no ID will generate:
/controller/action/
So all you need to do is put your value on the end. Try this:
$("#RelatedEntity").change(function () {
window.location = '#Url.Action("EntityIndex")' + $(this).val();
});
Should give you (assuming value is 23):
/controller/action/23