In my view I have a ActionLink that passes an Id to another View. I used this multiple times but for some reason it does not work on this ActionLink. I even tried with a AJAX POST call in javascript but with no success either. Am I doing something wrong? If so, I am not seeing what.
Controller:
The parameter Id in this function is 0 and should be filled.
public ActionResult NieuwPriveBericht(int Id)
{
TblPER_Personeelslid Sender = BCL.GetEmployeeByLoginName(Session["LoginName"].ToString());
TblPER_Personeelslid Receiver = BCL.GetEmployeeById(Id);
var Model = new TblALG_PrvBericht();
Model.Datum = DateTime.Now.Date;
Model.Zender = Sender.IDPersoneelslid;
Model.Ontvanger = Receiver.IDPersoneelslid;
ViewBag.ReceiverName = Receiver.Voornaam + " " + Receiver.Naam;
return View(Model);
}
public ActionResult PriveBerichten()
{
ViewBag.SelectedEmployee = "";
var Model = new PriveBerichten();
return View(Model);
}
View:
If I debug my view I clearly see #Model.SelectedOption filled.
#using (Html.BeginForm("PriveBerichten", "Home", #Model, FormMethod.Post))
{
#Html.ActionLink("Nieuw bericht maken", "NieuwPriveBericht", new { Id = #Model.SelectedOption }, new { #class = "button-add" })
}
AJAX CALL
$("#DdlEmployees").change(function () {
var SelectedEmployee = $('#DdlEmployees option:selected').val();
$.ajax({
type: "POST",
url: 'PriveBerichten?SelectedEmployee=' + SelectedEmployee, // this works
dataType: "json",
data: $('form').serialize(),
success: function () {
alert("test"); // does not show
},
error: function () {
}
});
})
If you didn't set up the id of route is "Id", you need to use "id". Also delete "#Model" in the BeginForm.
Action
public ActionResult NieuwPriveBericht(int id)
{
//
}
View:
#using (Html.BeginForm("PriveBerichten", "Home", FormMethod.Post))
{
#Html.ActionLink("Nieuw bericht maken", "NieuwPriveBericht",
new { id = #Model.SelectedOption }, new{ #class = "button-add" })
}
Thanks for showing the ActionResult that generates the view. I think this is your problem:
var Model = new PriveBerichten();
return View(Model);
I assume your class PriveBerichten contains the SelectedOption property? If you do not change/initialize this property value in the constructor of PriveBerichten it is 0 by default, and so it will be 0 in your actionlink.
Related
I have a DownloadExcel(List model) method in controller. I add a link in view page,
#model IEnumerable<MyNameSpace.Models.Page>
#if (Model != null)
{
if (Model.Count() != 0)
{
....
<div>
Download Excel
</div>
}
}
controller:
public void DownloadExcel(List<Page> model)
{
var collection = model;
ExcelPackage Ep = new ExcelPackage();
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
ExcelWorksheet Sheet = Ep.Workbook.Worksheets.Add("Report");
Sheet.Cells["A1"].Value = "id";
Sheet.Cells["B1"].Value = "Name";
Sheet.Cells["C1"].Value = "Title";
Sheet.Cells["D1"].Value = "CreatedDate";
Sheet.Cells["E1"].Value = "CreatedBy";
int row = 2;
foreach (var item in collection)
{
Sheet.Cells[string.Format("A{0}", row)].Value = item.Id;
Sheet.Cells[string.Format("B{0}", row)].Value = item.Name;
Sheet.Cells[string.Format("C{0}", row)].Value = item.Title;
Sheet.Cells[string.Format("D{0}", row)].Value = Convert.ToDateTime(item.CreatedDate);
Sheet.Cells[string.Format("E{0}", row)].Value = item.CreatedBy;
row++;
}
Sheet.Cells["A:AZ"].AutoFitColumns();
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment: filename=" + "Report.xlsx");
Response.BinaryWrite(Ep.GetAsByteArray());
Response.End();
}
How do I pass the Model data from view to controller action? It gives me a blank spreadsheet data right now. Thanks
You should not use Url.Action in this case. Url.Action usually use for GET method.
In this case you can use ajax post as
In cshtml
<button onclick="download()">Download Excel</button>
Add script tag in cshtml page
function download() {
var obj= #Html.Raw(Json.Encode(Model));
$.ajax({
url: '#Url.Content("/Home/DownloadExcel")',
dataType: 'json',
type: 'POST',
data: JSON.stringify(obj),
contentType: 'application/json',
success: function (data) {
alert("success");
}
});
}
In controller you add attribute HttpPost as
[HttpPost]
public void DownloadExcel(List<Page> model)
I've a view which includes radio buttons .. this view linked with a layout which has a banner image ...
My question is how to update the banner image once the user check the radio.
I've tried the following :
** The following code in the action method that will be called once the user checks the radio to retrieve the banner path then i store this path in viewbag :
string bannerPath = MyEntity.MyTable.Find(selectedRadioID).BannerURL.ToString();
ViewBag.Banner = bannerPath;
** In the layout i'm trying to read the viewbag value :
<img src="#ViewBag.Banner" />
** Pseudo code to get things clear :
// this function are called once the radio changed ...(it will return data through JSON to fill drop down list) :
function RadioOnchange() {
$.ajax({
type: "post",
url: "/MyController/MyMethod/",
data: { sid: $('input[name="radio"]:checked').val() },
datatype: "json",
traditional: true,
success: function (data) {
var selectlist = "<select id='ddl'>";
selectlist = selectlist + '<option value="">--Select--</option>';
for (var i = 0; i < data.length; i++) {
selectlist = selectlist + '<option value=' + data[i].Value + '>' + data[i].Text + '</option>';
}
selectlist = selectlist + '</select>';
$('#selectlist').html(selectlist);
}
});}
// in my controller i have the following method :
public ActionResult MyMethod(string sid)
{
sid = Convert.ToInt32(sid)
...
...
string bannerPath = MyEntity.MyTable.Find(sid).BannerURL.ToString();
ViewBag.Banner = bannerPath ;
return Json(dataReturnedToFillSelectList, JsonRequestBehavior.AllowGet);
}
but the banner doesn't appear.
Viewbag is not accessible in JsonResult, so your action should return more complex object:
public ActionResult MyMethod(string sid)
{
...
return Json(new {
BannerPath = bannerPath,
Data = dataReturnedToFillSelectList
});
}
then in your ajax success you can apply img src:
function RadioOnchange() {
$.ajax({
...
success: function (data) {
$('#banner').attr('src', data.BannerPath);
var selectlist = "<select id='ddl'>";
selectlist = selectlist + '<option value="">--Select--</option>';
for (var i = 0; i < data.Data.length; i++) {
....
}
selectlist = selectlist + '</select>';
$('#selectlist').html(selectlist);
}
});}
Try adding the [HttpPost] verb before the method. Your AJAX call is of type Post but your method is Get.
[HttpPost]
public ActionResult MyMethod(string sid)
{
sid = Convert.ToInt32(sid)
...
...
string bannerPath = MyEntity.MyTable.Find(sid).BannerURL.ToString();
ViewBag.Banner = bannerPath ;
return Json(dataReturnedToFillSelectList, JsonRequestBehavior.AllowGet);
}
I am stuck in publishing the result from JSON so left the success portion blank.
View
#model MvcApplication2.Models.About
#{
ViewBag.Title = "About";
}
<p> #Html.DisplayFor(m=>m.test) </p>
<p> #Html.DisplayFor(m=>m.test1) </p>
Model
public class About
{
public string test { get; set; }
public string test1 { get; set; }
}
Controller
public class HomeController : Controller
{
public JsonResult About()
{
ViewBag.Message = "Your app description page.";
About ab = new About()
{
test = "a",
test1 = "b"
};
return Json(ab, JsonRequestBehavior.AllowGet);
}
}
JQuery in external file
$(document).ready(function () {
var itemName = "#btn-about";
$(itemName).click(function () {
$.ajax({
type: 'GET',
dataType: 'Json',
url: '/Home/About',
success: function (data) {
var option = '';
},
error: function (xhr, ajaxOption, thorwnError) {
console.log("Error")
},
processData: false,
async: true
});
});
});
=> I am a bit confused now. Altough I get a result in JSON format using AJAX, I want to publish it in this View 'About'. The View already have #model defined, so as soon as I get the result, I want the view to load it automatically as I don't think its a good option to create html controls in Javascript.
=> Is it possible or do I have to fill control one by one.
=> I am new in to MVC, so could you let me know any good suggestion.
Controller:
public ActionResult About()
{
var model = repo.GetModel();
return PartialViewResult("about", model);
}
jQuery:
$.ajax("/Controller/About/", {
type: "GET",
success: function (view) {
$("#aboutDiv").html(view);
}
});
In Main View:
<div id="aboutDiv"><div>
You need to give your elements some id or class that will allow you to interact with them easily on the client. Then, when you get your response, take the values from the JSON data and update the elements (using the id/class to find it) with the new value. I'm assuming you don't have any special template defined for your strings, adjust the selectors in the code as necessary to account for it if you do.
View
<p class="testDisplay"> #Html.DisplayFor(m=>m.test) </p>
<p class="test1Display"> #Html.DisplayFor(m=>m.test1) </p>
Client code
$(document).ready(function () {
var itemName = "#btn-about";
$(itemName).click(function () {
$.ajax({
type: 'GET',
dataType: 'Json',
url: '/Home/About',
success: function (data) {
$('.testDisplay').html(data.test);
$('.test1Display').html(data.test1);
},
error: function (xhr, ajaxOption, thorwnError) {
console.log("Error")
},
processData: false,
async: true
});
});
});
Instead of returning the data you will have to return the view as string and the use jquery to replace the result.
Controller:
public JsonResult About()
{
var model = // Your Model
return Json((RenderRazorViewToString("ViewNameYouWantToReturn", model)), JsonRequestBehavior.AllowGet);
}
[NonAction]
public string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
Then using jquery you can replace the result in container for eg: div as follows:
$.ajax({
type: 'GET',
dataType: 'Json',
url: '/Home/About',
success: function (result) {
$("#divId").replaceWith(result);
},
I've got two models, there are.
public class CreateAssignmentViewModel {
...
public List<CreateAssignmentSelectedItem> SelectedItems { get; set; }
}
public class CreateAssignmentSelectedItem {
...
}
Now I've got a view where contains CreateAssignmentViewModel, as you can see above this class contains a property where is a List<CreateAssignmentSelectedItem>
#model Contoso.MvcApplication.Models.Assignment.CreateAssignmentViewModel
#{
ViewBag.Title = "Create Assignment";
...
}
#using (Html.BeginForm()) {
...
}
Inside of the Html.BeginForm, I've got a partial view. And in it I've got a button using ajax where updates the partial view.
Look the following events. Where says data: I do not know what to enter to access only the property SelectedItems
var addQuestionToAssignmentContent = function (questionId)
{
$.ajax({
url: "/Assignment/AddItemToAssignmentContent",
type: "post",
data: { model: $(this).serialize() /* HERE I DON'T KNOW TO ACCESS THE */, itemId: questionId },
success: function (response) {
var $target = $("#assignmentContent");
var $newHtml = response;
$target.replaceWith($newHtml);
}
});
};
public ActionResult AddItemToAssignmentContent(List<CreateAssignmentSelectedItem> model, string itemId)
{
...
PartialView(..);
}
How can I do to pass only the object in the method?
First, give your form an ID:
#using (Html.BeginForm("actionName", "controllerName", FormMethod.Post, new{id = "frmUpdate"})) {
Second, change your code to be like this:
var f = $("#frmUpdate");
$.ajax({
url: f.attr('action'),
type: f.attr('method'),
data: f.serialize(),
//etc..
I use this in most cases and it works just nice. The data should automatically be bound to the model you have in your update action. So, for example... if you have a #model of type MyModel then in the update action it should look something like this:
[HttpPost]
public ActionResult Update(MyModel updatedModel)
Sometimes I work with a front end guy and he might not adhere to pass in the correct model, he might change the form fields or whatever. In this case I just let him serialize the form and pass it to the action an any way he wants.
I then use the FormCollection object to get the data I need.
Your json call
var addQuestionToAssignmentContent = function (questionId)
{
$.ajax({
url: "/Assignment/AddItemToAssignmentContent",
type: "post",
data: { model: $(this).serialize() /* HERE I DON'T KNOW TO ACCESS THE */, itemId: questionId },
success: function (response) {
var $target = $("#assignmentContent");
var $newHtml = response;
$target.replaceWith($newHtml);
}
});
};
Get a form collection object
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddItemToAssignmentContent(FormCollection collection)
{
vars someValue = collection.GetValue("somefield").AttemptedValue;
}
But if I would have control of front-end as you do then as Matt suggested you should use an pass a model;
here's my action.
public virtual JsonResult AddSearch()
{
var data = new { Id = food.Id, Image = food.Image, Name = food.Name};
return Json(data, JsonRequestBehavior.AllowGet);
}
here's my aJax form
#using (Ajax.BeginForm("AddSearch", "Home", new AjaxOptions { OnSuccess = "AddSearch" }))
my javascript file.
function AddSearch() {
alert("sdfsdfsdf");
}
it works, I see the alert box. my question is how I can get the "Id", "Name" and "Image" returned by JsonResult. I tried
alert("sdfsdfsdf");
it's not working.
MVC (to be precise unobtrusiveAjax helpers) will pass the standard jQuery.ajax success(data, textStatus, jqXHR)callback arguments to the OnSuccess method.
So you just need to add the parameters to your AddSearch method:
function AddSearch(data, status, xhr) {
// you can access your properties from data
alert(data.Name);
}
This is how i did... I accessed the list in my model and converted it to a JSON in my javascript.
var JsonServerList = <%= new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(#Model.ServerList) %>;
Now when i say ServerList[i].servername i get the values.
You can try something like this:
In the controller:
public virtual JsonResult AddSearch()
{
var data = new { Id = food.Id, Image = food.Image, Name = food.Name};
return Json(data, JsonRequestBehavior.AllowGet);
}
In the view/javascript section:
function AddSearch() {
$.getJSON("#url.Action(here_goes_your_actionname)", { parameters }, function (data) {
alert(data);
});
}
Hope this helps.
There is one more property in AjaxOption "UpdateTargetId" where your response will append.
your View like
<div id="tagetId">
</div>
#using (Ajax.BeginForm("AddSearch", "Home", new AjaxOptions { OnSuccess = "AddSearch", UpdateTargetId = "tagetId" }))
{
}
In your Controller
public Actionresult AddSearch()
{
var data = new { Id = food.Id, Image = food.Image, Name = food.Name};
return data;
}
you result will be Append in "targertId".