Pass Model Data to Url.Action Method - asp.net-mvc

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)

Related

How to update Layout banner image based on path sent from the controller?

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);
}

Html.ActionLink does not pass my id

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.

how i can i handle the returned Json to construct another Ajax.actionlink

I have the following Ajax.actionlink which will the action method and return a JSON:-
#Ajax.ActionLink("Start Process", "StartProcess", "Home",
new { name = "BuisnessProcess" },
new AjaxOptions
{ HttpMethod = "POST",
LoadingElementId = "tobehide2",
UpdateTargetId = "startprocess",
OnSuccess = "Animate" })
</div> <img id="tobehide2" src="~/Content/ajax-loading2.gif" />
Currently when the user clicks on the link it will display the JSON info in the browser:-
{"activityId":"2119_666_BuisnessProcess_process1_setverialbe","processId":"666_BuisnessProcess_process1"}
But what i trying to do is to build another Ajax.actionlink based on the returned Json and pass the activityId as a new parameter to the Ajax.actionlink.
Best Regards
:::UPDATED:::
[HttpPost]
public ActionResult StartProcess(string name)
{
using (var client = new WebClient())
{
try
{
var query = HttpUtility.ParseQueryString(string.Empty);
query["j_username"] = "kermit";
query["hash"] = "9449B5ABCFA9AFDA36B801351ED3DF66";
query["loginAs"] = User.Identity.Name;
query["imagurl"] = "123";
var url = new UriBuilder("http://localhost:8080/jw/web/json/workflow/process/start/" + name.ToString() + ":28:process1");
url.Query = query.ToString();
string json = client.DownloadString(url.ToString());
Thread.Sleep(500);
return Content("Process started succsfully. Returned values are :-" + json);
}
catch (System.Net.WebException ex)
{
return Content("", "application/json");
}
}
}
when you return data in action, to combine html string.
test
to UpdataTargetId : startprocess.
when you return the json to view, then execute "Animate" function.
so, you can construct the link in Animate.
function Animate(result)
{
$(result).each(function(index, item){
// todo construct the link
});
}

asp.net mvc3, how to get the value returned by JsonResult

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".

Return PDF to browser using JSON and MVC?

I have a link as follows.
#Html.ActionLink("Create Report", "Screenreport", "Reports", null, new { #class = "subNavA AddBorderTop", id = "screenReport", title = "Create Report" })
Once the link is clicked, I have a the following jQuery code which creates a JSON object and post the information.
$().ready(function () {
// Create Report fron the screen data
$("#screenReport").live("click", function (event) { GenerateScreenReport(this, event); });
}) /* end document.ready() */
function GenerateScreenReport(clikedtag, event) {
var table = $(".EvrakTable").html();
var screendata = tableParser(table);
var Screentable = { Screenlist: screendata };
var myurl = $(clikedtag).attr("href");
var title = $(clikedtag).attr("title");
$.ajax({
url: myurl,
type: 'POST',
data: JSON.stringify(Screentable),
dataType: 'json',
contentType: 'application/json',
success: function () { alert("Got it"); }
});
};
To Handle JSON I have the following two classes. Realize two classes in the same namespace
namespace MyProject.ViewModels
{
public class Screenrecord
{
public string Fname{ get; set; }
public string LName { get; set; }
public string Age { get; set; }
public string DOB { get; set; }
}
public class Screentable
{
public List<Screenrecord> Screenlist { get; set; }
}
}
ANd in my controller, I have the following code:
[HttpPost]
public FileStreamResult Screenreport(Screentable screendata)
{
MemoryStream outputStream = new MemoryStream();
MemoryStream workStream = new MemoryStream();
Document document = new Document();
PdfWriter.GetInstance(document, workStream);
document.Open();
document.Add(new Paragraph("Hello World"));
document.Add(new Paragraph(DateTime.Now.ToString()));
document.Close();
byte[] byteInfo = workStream.ToArray();
outputStream.Write(byteInfo, 0, byteInfo.Length);
outputStream.Position = 0;
return new FileStreamResult(outputStream, "application/pdf");
}
This code is supposed to gerate PDF.
if I leave [HttpPost] as it is, it does NOT generate PDF and it goes to /Screenreport page, however I see my JSON is passed to the controller properly.
(screendata is populated properly - in controller)
But if I comment out [HttpPost], it DOES generate a PDF but screendata (in controller) is null.
Can someone please explain whats's going on and help me figure it out. Thanksin advance.
You cannot use AJAX to download files, because javascript doesn't allow you to save the downloaded content.
To workaround this you need to take 2 steps.
First: make the HTTP Post request, and in the controller action we would store the File content in a Memory stream.Second: on success make another call by setting the window.location to the Download Action method
In your Controller create this 2 actions:
public ActionResult GenerateFile()
{
MemoryStream fileStream = new MemoryStream { Position = 0 };
//position = 0 is important
var fName = string.Format("File-{0}.xlsx", DateTime.Now.ToString("s"));
Session[fName] = fileStream;
return Json(new { success = true, fName }, JsonRequestBehavior.AllowGet);
}
public ActionResult DownloadFile(string fName)
{
var ms = Session[fName] as MemoryStream;
if (ms == null)
return new EmptyResult();
Session[fName] = null;
return File(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fName);
}
In your javascript:
$('#Donwload-button').click(function () {
data = JSON.stringify(YOURDATA);
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: "/YOURCONTROLLER/GenerateFile",
data: data,
success: function (d) {
if (d.success) {
window.location = "/YOURCONTROLLER/DownloadFile" + "?fName=" + d.fName;
}
},
error: function () {
alert("Error");
}
});
});
I feel obligated to post my answer since I didn't hear from anyone. I ended up creating a form that includes a hidden input, then saved my json object in the hidden input and then submit the form. This time I will get input as an string not a json or xml.
var $hidInput = $("#dataToReport");
$hidInput.val(JSON.stringify(Screentable));
$('#frmScreenreport').submit();
Thanks all anyways.

Resources