I am creating an MVC 4 application. I am using Rotativa to generate pdfs
they have a method called
public ActionAsPdf(string action, object routeValues);
I am having trouble passing in a complex object to the routeValues
i.e:
I have a viewModel
public class FullName
{
public string FirstName { get; set; }
public string Surname { get; set; }
}
public ActionResult Index(FullName name)
{
ViewBag.Message = string.Format("Hello {0} to ASP.NET MVC!", name);
return View();
}
public ActionResult Test()
{
var fullname = new FullName();
fullname.FirstName = "John";
fullname.Surname = "Smith";
return new ActionAsPdf("Index", new { name = fullname }) { FileName = "Test.pdf" };
}
when I step through, in the Index action the name is null... how do I pass the complex model through?
Check this
return new ActionAsPdf("Index", fullname ) { FileName = "Test.pdf" };
public ActionResult viewForPDFFile(int id)
{
Data data = new Manager().GetData(id);
return View(data); // this view content will show in PDF File
}
then call it simply
return new ActionAsPdf("viewForPDFFile", new { id = id} ) { FileName = String.Format("File_{0}.pdf",id) };
Related
I have a SOAP web service that someone developed at my work place and i try to learn it and i came across a move in the code that i can't get my head around. can someone explain to me the logic behind it? why would someone want to serialize an object and a line after to deserialize it?
**this is the whole code: if someone has a way to improve the code it will be appreciated: **
using IRail.BLL.SAP;
using IRail.Entities.SAP.Report;
using IRail.WebAPI.Heplers;
using Logger;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Web.Script.Serialization;
using System.Web.Services;
namespace IRail.WebAPI
{
public class EventInfo
{
public string QMNUM { get; set; }
public string QMART { get; set; }
public string STATUS { get; set; }
public string MAHUT_CODE { get; set; }
public string MAHUT_TXT { get; set; }
public string START_DATE { get; set; }
public string START_TIME { get; set; }
public string END_DATE { get; set; }
public string END_TIME { get; set; }
public string ZQMNUM { get; set; }
public string QMTXT { get; set; }
public string IKUN { get; set; }
public string ZLONG { get; set; }
public string LAT { get; set; }
public string TPLNR { get; set; }
public string ZZKM_NUM { get; set; }
public string ZZTOKM_NUM { get; set; }
}
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class Events : System.Web.Services.WebService
{
public static readonly ILogger _logger = LogManager.GetLogger();
[WebMethod]
public string UpdateEvent(EventInfo eventInfo)
{
// create an instance of SapClient object an fill it with the input parameters,
// that passes by the url to the function using the eventInfo class.
SapClient SapArgs = new SapClient()
{
params_input = "",
QNUM = eventInfo.QMNUM,
QMART = eventInfo.QMART,
STATUS = eventInfo.STATUS,
MAHUT_CODE = eventInfo.MAHUT_CODE,
MAHUT_TXT = eventInfo.MAHUT_TXT,
START_DATE = eventInfo.START_DATE,
START_TIME = eventInfo.START_TIME,
END_DATE = eventInfo.END_DATE,
END_TIME = eventInfo.END_TIME,
ZQMNUM = eventInfo.ZQMNUM,
QMTXT = eventInfo.QMTXT,
IKUN = eventInfo.IKUN,
ZLONG = eventInfo.ZLONG,
LAT = eventInfo.LAT,
TPLNR = eventInfo.TPLNR,
ZZKM_NUM = eventInfo.ZZKM_NUM,
ZZTOKM_NUM = eventInfo.ZZTOKM_NUM,
ikunx = "",
ikuny = "",
operation_type = "",
returnZ = "",
returnM = "",
returnTrueCurves = "",
f = ""
};
string errorMsg = String.Empty;
string outputJson = String.Empty;
ApiHelper apiHelper = new ApiHelper();
try
{
// create an instance of JS Serializer.
var jss = new JavaScriptSerializer();
// serialize the object to convert it to json format.
JObject sapArgs = JObject.Parse(jss.Serialize(SapArgs));
// decerialize the object back from json format to pass the JSON string representation
// of the sapArgs object as the input to the callGPAsync method.
var dict = jss.Deserialize<Dictionary<string, string>>(sapArgs.ToString());
// create an instance of EventsEngine.
EventsEngine eventsEngine = new EventsEngine();
// assign the type of the event to the events object:
// check the event type.
SapArgs.operation_type = eventsEngine.CheckEventType(dict, ref errorMsg);
// assign the event type that has returned to the sapArgs object's operation_type parameter.
sapArgs["operation_type"] = SapArgs.operation_type; // "1";// set operation_type for test;
// if encountered an error return the content of it.
if (errorMsg != "") return "UpdateEvent ERROR: " + errorMsg;
_logger.Info($"Username: {Utils.GetUserName()}, UpdateEvent : {sapArgs.ToString()}, eventType :{SapArgs.operation_type}");
if (!string.IsNullOrWhiteSpace(apiHelper.getValueFromDict(dict, "IKUN")) && dict["IKUN"].ToString() == "Y")
{
var res = apiHelper.convertCoordiateWGSToITM(sapArgs).GetAwaiter().GetResult();
}
outputJson = apiHelper.callGPAsync(sapArgs).GetAwaiter().GetResult();
try
{
// if there is result from submitted job add operation_type
outputJson = outputJson.Replace("}", ", \"operation_type\" = \"" + SapArgs.operation_type + "\" }");
}
catch (Exception outputEx)
{
return "outputJson ERROR: " + outputEx;
}
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(outputJson, System.Text.Encoding.UTF8, "application/json");
return outputJson;
}
catch (Exception ex)
{
_logger.Error(" UpdateEvent ERROR : " + SapArgs.ToString() + ", eventType :" + SapArgs.operation_type + ", errorMsg :" + errorMsg);
_logger.Error(ex);
return "UpdateEvent ERROR: update failed on exception. please check logs.";
}
//0. check with documentation - what are the parameters - in sap document
//0. log -> input call
//1. properties input validation -
// A. all inputs are correct //2.4 in documents ---> function in BLL that does the validation
//2. if all ok - -- delete prev event
//3. call GP service to update new event
//4. return success + log reult
}
}
}
I did not try anything i just want to understand the logic.
From a data table, I have generated a text file that I want to export as a .txt or .csv file using a controller action return. In aspx I was able to use:
MeetingListTxt = stringBuilder.ToString();
base.Response.Clear();
base.Response.AddHeader("content-disposition", "attachment;filename=MeetingList.csv");
base.Response.Charset = "";
base.Response.ContentType = "application/text";
base.Response.Output.Write(stringBuilder.ToString());
base.Response.Flush();
base.Response.End();
The result was a text file that the user could save to his hard drive.
How can this be done with Aspnet core 3?
As far as I know, in asp.net core we could use FileResult to generate the response which download the text file.
The FileResult will automatically provide the proper Content-Disposition header to attachment.
More details, you could refer to below test demo codes:
public class Student
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public IActionResult DownloadCommaSeperatedFile()
{
List<Student> students = new List<Student>
{
new Student { Id = 1, FirstName = "Joydip", LastName = "Kanjilal" },
new Student { Id = 2, FirstName = "Steve", LastName = "Smith" },
new Student { Id = 3, FirstName = "Anand", LastName = "Narayaswamy"}
};
try
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("Id,FirstName,LastName");
foreach (var student in students)
{
stringBuilder.AppendLine($"{student.Id}, { student.FirstName},{ student.LastName}");
}
return File(Encoding.UTF8.GetBytes
(stringBuilder.ToString()), "text/csv", "student.csv");
}
catch
{
return Error();
}
}
Result:
I defined both FixedLength and Delimited attributes on a single class. It reads the fixed length file fine but fails when i try to write out a csv.
[FixedLengthRecord]
[DelimitedRecord(",")]
public class PCFFileHeader
{
[FieldFixedLength(2)] public string RecordType { get; set; }
[FieldFixedLength(25)] public string FileDescription { get; set; }
}
var engine = new MultiRecordEngine(typeof(PCFFileHeader), typeof(SecondHeader));
engine.RecordSelector = RecordSelector;
var output = engine.ReadFile(filePath);
// code to extract PCFHeader from output and create a list
var headerEngine = new DelimitedFileEngine<PCFFileHeader>();
headerEngine.WriteFile("header_" + DateTime.Now.ToString("yyyyMMddhhmmss"), pcfFileHeaderList);
You can't add both [FixedLengthRecord] and [DelimitedRecord] to the same class. FileHelpers will just treat it as [FixedLengthRecord]. With your current class, it will error if you do:
// This causes an exception because the class is not a delimited record definition
var delimitedHeaderEngine = new DelimitedFileEngine<PCFFileHeader>();
Instead, you should have two PCFFileHeader definitions, FixedPCFFileHeader and DelimitedPCFFileHeader.
[FixedLengthRecord]
public class FixedPCFFileHeader
{
[FieldFixedLength(2)] public string RecordType { get; set; }
[FieldFixedLength(25)] public string FileDescription { get; set; }
}
[DelimitedRecord(",")]
public class DelimitedPCFFileHeader
{
public string RecordType { get; set; }
public string FileDescription { get; set; }
}
class Program
{
static void Main(string[] args)
{
var fixedHeaderEngine = new FileHelperEngine<FixedPCFFileHeader>();
var recordsFixed = fixedHeaderEngine.ReadString("AADescription ");
Debug.Assert(recordsFixed.Count() == 1);
Debug.Assert(recordsFixed[0].RecordType == "AA");
Debug.Assert(recordsFixed[0].FileDescription == "Description ");
var delimitedHeaderEngine = new FileHelperEngine<DelimitedPCFFileHeader>();
var recordsDelimited = delimitedHeaderEngine.ReadString("AA,Description");
Debug.Assert(recordsDelimited.Count() == 1);
Debug.Assert(recordsDelimited[0].RecordType == "AA");
Debug.Assert(recordsDelimited[0].FileDescription == "Description");
var pcfFileHeaderList = new FixedPCFFileHeader[] { new FixedPCFFileHeader() { RecordType = "AA", FileDescription = "Description" } };
// If you want to output a header when exporting uncomment the following
//headerEngine.HeaderText = "header_" + DateTime.Now.ToString("yyyyMMddhhmmss");
var output = fixedHeaderEngine.WriteString(pcfFileHeaderList);
Debug.Assert(output == "AADescription \r\n");
Console.WriteLine("All OK");
Console.ReadLine();
}
}
If you want to automatically detect the correct format during import, you can use the FileHelpers Smart Format Detector.
when click edit link in index page
it give me error
The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies.Employee_2EF71CC17A29BA91B02BC5CDB0EE5AF82D363EEF7E174A21C9546772913AA929', but this dictionary requires a model item of type 'WebCourse.Models.Customemployee'.
I have custom model Customemployee
namespace WebCourse.Models Customemployee
{
public class Customemployee
{
//represent employee table in database
public string Name { get; set; }
public int Salary { get; set; }
public string Email { get; set; }
public int DistrictId { get; set; }
//represent employee course table in database
public List<EmployeeCourse> Courses { get; set; }
//represent employee language table in database
public List<EmployeeLangage> Langs { get; set; }
}
}
and my controller empcourse
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebCourse.Models;
using System.Data.Entity;
namespace WebCourse.Controllers
{
public class empcourseController : Controller
{
mycourseEntities db = new mycourseEntities();
// GET: empcourse
public ActionResult Index()
{
var query = db.Employees.ToList().Select(p => new EmpInfo
{
Id = p.Id,
Name = p.Name,
Salary = Convert.ToInt32( p.Salary),
Email = p.Email,
DistrictName = p.Destrict.DistrictName,
CityName = p.Destrict.City.CityName,
CountryName = p.Destrict.City.Country.CountryName,
CourseNames = p.EmployeeCourses.Select(t => t.Course.CourseName).ToList(),
LanguageName = p.EmployeeLangages.Select(t => t.Language.LnaguageName).ToList(),
levelName = p.EmployeeLangages.Select(t => t.Level.LevelName).ToList(),
CourseName = string.Join(",", p.EmployeeCourses.Select(t => t.Course.CourseName).ToList())
});
return View(query);
}
public ActionResult Create()
{
ViewBag.CountryId = new SelectList(db.Countries, "Id", "CountryName");
ViewBag.LanaguageId = new SelectList(db.Languages.ToList(), "Id", "LnaguageName");
ViewBag.LevelId = new SelectList(db.Levels.ToList(), "Id", "LevelName");
ViewBag.CourseId = new SelectList(db.Courses.ToList(), "Id", "CourseName");
return View();
}
public ActionResult Edit(int id)
{
//how to pass data from index view to edit view
Employee old = db.Employees.Find(id);
return View(old);
}
[HttpPost]
public ActionResult Create(Customemployee cemp)
{
using (mycourseEntities db = new mycourseEntities())
{
Employee E = new Employee { Name = cemp.Name, Salary = cemp.Salary, Email = cemp.Email, DistrictId = cemp.DistrictId };
foreach (var i in cemp.Courses)
{
E.EmployeeCourses.Add(i);
db.SaveChanges();
}
foreach (var i in cemp.Langs)
{
E.EmployeeLangages.Add(i);
db.SaveChanges();
}
db.Employees.Add(E);
db.SaveChanges();
}
return View();
}
public JsonResult getcitybyid(int id)
{
db.Configuration.ProxyCreationEnabled = false;
return Json(db.Cities.Where(a => a.CountryId == id), JsonRequestBehavior.AllowGet);
}
public JsonResult getdistrictbyid(int id)
{
db.Configuration.ProxyCreationEnabled = false;
return Json(db.Destricts.Where(a => a.CityId == id), JsonRequestBehavior.AllowGet);
}
}
}
the error show here in code
public ActionResult Edit(int id)
{
//how to pass data from index view to edit view
Employee old = db.Employees.Find(id);
return View(old);
}
How to pass data from index view that show data to edit view
From the error message, it looks like your Edit view is strontly typed to Customemployee type. That means you should be passing an object of Customemployee class from your Edit action method to this view. But your current code is sending an object of Employee type.
So update your Edit action method to send the correct object to the view.
public ActionResult Edit(int id)
{
Employee old = db.Employees.Find(id);
if(old!=null)
{
var vm = new CustomEmployee();
vm.Name = old.Name;
vm.Email = old.Email;
// Assign other property values as needed.
return View(vm);
}
return Content("No employees found for the Id passed");
// to do : Ideally return a "NotFound" view
}
I'm having trouble with binding a ListView from Odata, when I was working with local Db I was able to do the data binding returning a list in my ModelView class into my list variable through the get method, but with the Odata the method is Async, so I'am not able to return the list, and some how if i fill the variable in the method, it doesn't work, and at this point I cant find the solution, if someone could help me, I will really appreciate it, here is my code so far:
ViewModel class:
public class Page1ViewModel
{
public string Nombre { set; get; }
public string Direccion { set; get; }
public string Descripcion { set; get; }
public string Logo { set; get; }
public List<Restaurant> RestaurantDb { get; set; }
public async void GetRestaurant()
{
String str = "";
try
{
var x = ODataDynamic.Expression;
var client = new ODataClient("http://192.168.0.9/WSTestDev/WSTestDev.svc/");
var packages = await client.FindEntriesAsync("Restaurant");
foreach (var package in packages)
{
var rt = new Restaurant
{
Nombre = package["Nombre"].ToString(),
Direccion = package["Direccion"].ToString(),
Descripcion = package["Descripcion"].ToString(),
Logo = package["Logo"].ToString()
};
RestaurantDb.Add(rt);
}
}
catch (Exception err)
{
str = err.ToString();
}
}
}
View Class:
public partial class Page1 : ContentPage
{
public Page1ViewModel vm;
public Page1()
{
vm = new Page1ViewModel();
vm.GetRestaurant();
BindingContext = vm;
InitializeComponent();
}
Instead of List<Restaurant>, use ObservableCollection<Restaurant>. It behaves similarly to List, but will notify the UI of any changes to it's contents so that the UI can update.
Alternately, you could await vm.GetRestaurant(), but that will require more restructuring of your code.