Rotativa generating blank PDF in Server - asp.net-mvc

We are using Rotativa in a .Net MVC 5 project. it works like a charm locally and fails (generates a blank PDF) equally when deployed to server. However, if I login to server and access the website as localhost it generates PDF just fine.
So it looked like a permission issue with which Application pool is running on. So, for testing purpose, I changed to run the App Pool to run on "Local System". Still same issue.
We have also tried:
"ViewasPDF"
App settings which looks like: <add key="WkhtmltopdfPath" value="<path to the folder>"/>
Below is the code:
return new ActionAsPdf("ActionMethod",new { id = id, partSelected = part, selectedTab = selectedTab, isDownload = true })
{
FileName = fileName,
PageMargins = { Left = 0, Right = 0 },
CustomSwitches = "--disable-external-links --disable-internal-links --disable-smart-shrinking --viewport-size 1600x900 --load-error-handling ignore",
PageOrientation = Rotativa.Options.Orientation.Portrait,
PageSize = Rotativa.Options.Size.A4,
PageWidth = 210,
PageHeight = 297
};

First, you have disabled displaying error with the custom switch --load-error-handling ignore. It might help to not have it disabled temporarily for the purpose of debugging.
Secondly, a blind guess from me is that you may have some images that require local path as src on the pdf? If that's the case you will need #Server.MapPath for each one of those.
For example:
<img src="#Server.MapPath("your image path")"/>

var iResult = new Rotativa.ActionAsPdf("PrintForm", new { Id = Id }) { FileName = iFilename, SaveOnServerPath = ViewBag.FileName };
iResult.UserName = System.Configuration.ConfigurationManager.AppSettings["ADUserID"].ToString();
iResult.Password = System.Configuration.ConfigurationManager.AppSettings["ADPassword"].ToString();
return iResult;
Here is a code example where aduser is user name and password, please create a generic user account for this..

Related

Random image from folder

How can I make possible that the app will load all of the images from the specific folder and then put in array and choose one image randomly? When chose one then pass to the fronted to show the image. How to do that too?
I am C# developer but not long time ago I found ElectronJS and this framework does everything easier so therefore I am moving to this framework.
I did in C# programming this way:
// basic settings.
var ext = new List<string> { ".jpg", ".gif", ".png" };
// we use same directory where program is.
string targetDirectory = Directory.GetCurrentDirectory() + "\\assets\\" + "images\\" + "animals\\";
// Here we create our list of files
// New list
// Use GetFiles to getfilenames
// Filter unwanted stuff away (like our program)
if (Directory.Exists(targetDirectory))
{
Files = new List<string>
(Directory.GetFiles(targetDirectory, "*.*", SearchOption.TopDirectoryOnly)
.Where(s => ext.Any(es => s.EndsWith(es))));
// Show first picture so we dont need wait 3 secs.
ChangePicture();
}
else
{
panel5.BackgroundImage = new Bitmap(Resources.doggy);
}
I don't know how to do in ElectronJS.
Thank you in advance the answers.
Alright. I found the solution.
However I don't understand the people who are giving negative reputation for the opened question. If they are giving negative reputation then they could explain why.
Well anyway, I did fix this issue with this way:
I created images.js file and added this:
var fs = require('fs');
function getRandImage() {
var files = fs.readdirSync('./assets/images/animals/')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
console.log('../assets/images/animals/' + chosenFile);
return '../assets/images/animals/' + chosenFile;
}
module.exports = { getRandImage }
I used console to see if the value is correct, otherwise others can delete that part.
Sending the data to the renderer process:
const { getRandImage } = require('./images');
child.webContents.send('random-image', getRandImage());
I did put in the preload.js file the following (I used the starter pack electronjs github to start with something):
var { ipcRenderer } = require('electron');
ipcRenderer.on('random-image', function (event, store) {
document.getElementById("randompic").src = store;
console.log(store);
});
Same here, I did use console.log just for test the value is correct and I used to change the randompic ID related image src html to the randomly chosen image.
Hopefully I did helping those people who are newbie as me.

Azure DevOps Server 2019 Programmatially copy test case error Exception: 'TF237124: Work Item is not ready to save'."

I'm able to copy most test cases with this code (trying to copy shared steps to be part of the test case itself) but this one will not copy but I can not see any error message as to why - could anyone suggest anything else to try. See output from Immediate windows. Thanks John.
?targetTestCase.Error
null
?targetTestCase.InvalidProperties
Count = 0
?targetTestCase.IsDirty
true
?targetTestCase.State
"Ready"
?targetTestCase.Reason
"New"
foreach (ITestAction step in testSteps)
{
if (step is ITestStep)
{
ITestStep sourceStep = (ITestStep)step;
ITestStep targetStep = targetTestCase.CreateTestStep();
targetStep.Title = sourceStep.Title;
targetStep.Description = sourceStep.Description;
targetStep.ExpectedResult = sourceStep.ExpectedResult;
//Copy Attachments
if (sourceStep.Attachments.Count > 0)
{
string attachmentRootFolder = _tfsServiceUtilities.GetAttachmentsFolderPath();
string testCaseFolder = _tfsServiceUtilities.CreateDirectory(attachmentRootFolder, "TestCase_" + targetTestCase.Id);
//Unique folder path for test step
string TestStepAttachementFolder = _tfsServiceUtilities.CreateDirectory(testCaseFolder, "TestStep_" + sourceStep.Id);
using (var client = new WebClient())
{
client.UseDefaultCredentials = true;
foreach (ITestAttachment attachment in sourceStep.Attachments)
{
string attachmentPath = TestStepAttachementFolder + "\\" + attachment.Name;
client.DownloadFile(attachment.Uri, attachmentPath);
ITestAttachment newAttachment = targetTestCase.CreateAttachment(attachmentPath);
newAttachment.Comment = attachment.Comment;
targetStep.Attachments.Add(newAttachment);
}
}
}
targetTestCase.Actions.Add(targetStep);
targetTestCase.Save();
}
Since this code works for most test cases, this issue may come from the particular test case. In order to narrow down the issue, please try the following items:
Run the code on another client machine to see whether it works.
Try to modify this particular test case using the account API uses, to see whether it can be saved successfully.
Try validate the WorkItem prior to save. The validate() method will return an arraylist of invalid fields.

why asp.net mvc does not include the image uploaded folder in the project?

what I have found that the images uploaded by my application are not included in the project and that I have to include them manually image by image so what is the correct way of asp.net mvc project to let the images uploaded to be included in the project.
The following code is the one that upload the images to the folder and creates a unique name for each image. but still those images are not included in the project explorer.
public ActionResult Create(Job job, HttpPostedFileBase JobImage)
{
var value = "999999999";
var result4 = from app in db.Job where app.UniqueJobImageName.Contains(value) select app;
if(result4.FirstOrDefault() != null)
{
value = generateRandom();
}
if (ModelState.IsValid && CheckFileType(JobImage.FileName))
{
string ext = Path.GetExtension(JobImage.FileName);
var fileName = Path.GetFileName(JobImage.FileName);
job.JobImage = JobImage.FileName;
job.UniqueJobImageName = value + ext;
var path = Path.Combine(Server.MapPath("~/Images"), value + ext);
JobImage.SaveAs(path);
job.UserId = User.Identity.GetUserId();
job.jobUrl = "";
job.Month = DateTime.Now.ToString("MMMM");
job.DateAndTime = DateTime.Now;
AllJobModel all = new AllJobModel
{
JobTitle = job.JobTitle,
JobDescription = job.JobDescription,
JobImage = job.JobImage,
UniqueJobImageName = job.UniqueJobImageName,
locationName = job.locationName,
minimumSalary = job.minimumSalary.ToString(),
maximumSalary = job.maximumSalary.ToString(),
jobUrl = job.jobUrl,
PostedDate = DateTime.Now.ToString("dd/MM/yyyy"),
UserId= User.Identity.GetUserId(),
};
db.AllJobModel.Add(all);
db.SaveChanges();
db.Job.Add(job);
db.SaveChanges();
return RedirectToAction("Index","Home");
}else if (!CheckFileType(JobImage.FileName))
{
}
return View(job);
}
enter image description here
This doesn't make any sense. The uploaded images are content created by the user. They are not a deployable component of the site (or, they shouldn't be anyway). They are user-generated content, not developer resources.
If you are looking to effectively migrate your data (i.e. copy database entries and other user-generated content such as image files) from one environment to another, then that is a separate task for which you can create a separate process and/or automated script. Don't confuse it with the job of uploading a new version of your application code.
P.S. Even if what you were asking for was a sensible goal, it's impossible anyway - the executable version of your code is not the same as the code you see in Visual Studio in your project. In a modern ASP.NET application the executable code is in a different folder (even when you're running in debug mode in Visual Studio) and it has no concept or knowledge of the original project it was compiled from, or where to find it, or how to interact with it.

Rotativa BuildPdf is working on local computer but not on production server

I am using Rotativa to generate a pdf from a view I have created. Locally this works fine, the pdf is stored on my local computer and the email functiont then attaches and sends the file. But when I release it on our server, it basically breaks at this part:
var binary = pdf.BuildPdf(this.ControllerContext);
The website takes ages to load and then finally just says
Sorry, an error occurred while processing your request.
What i did to test this was to redirect to the actual view which will be generated in a pdf until this error was shown. I thought the issue was that the website does not have any write rights but could create directories in the required folder up until the above part mentioned.
What can I do to solve this?
Here is my full section of code for this part:
string Switches = string.Format("--print-media-type --header-html {0} --footer-html {1}", Url.Action("Header", "Home", new { area = "" }, "http"), Url.Action("Footer", "Home", new { area = "" }, "http"));
var fileName = ReportName+objScor.Name+"_"+objScor.Surname + DateTime.Now.ToString("dd MMM yyyy HHmmss") + ".pdf";
var filePath =(#"C:\\PDFReport\\" + fileName);
if (!System.IO.File.Exists(#"C:\\PDFReport\\"))
{
Directory.CreateDirectory(#"C:\\PDFReport\\");
}
var pdf = new Rotativa.ViewAsPdf("Report", report)
{
FileName = fileName,
CustomSwitches = Switches
};
var binary = pdf.BuildPdf(this.ControllerContext);
Thanks in advance.

MonoTouch SecKeyChain.Add returning SecStatusCode.Param

I'm trying to save a record like so:
var testRecord = new SecRecord(SecKind.GenericPassword)
{
CreationDate = DateTime.UtcNow,
MatchCaseInsensitive = false,
Service = "MyService",
Label = "MyService",
Account = "User",
Generic = NSData.FromString("test", NSStringEncoding.UTF8),
};
SecKeyChain.Add(testRecord);
...but I'm getting SecStatusCode.Param back when I run it in the simulator. According to the documentation, that code means "Invalid or incomplete parameters passed" but I don't see anything missing or unusual that others aren't doing with apparent success.
Even adding CreationDate, Invisible, Description, Comment, Accessible, and ValueData properties to the SecRecord (some as in this example) didn't help -- still getting SecStatusCode.Param.
Are there any non-obvious things that might cause a Param status code to be returned?
I had a lot of trouble trying to use the keychain. I finally got mine working to store user credentials in the app. Here is what I have:
SecRecord existingRec = new SecRecord (SecKind.GenericPassword) {
Service = Keychain.USER_SERVICE,
Label = Keychain.USER_LABEL
};
var record = new SecRecord (SecKind.GenericPassword) {
Service = Keychain.USER_SERVICE,
Label = Keychain.USER_LABEL,
Account = username,
ValueData = NSData.FromString (password),
Accessible = SecAccessible.Always
};
SecStatusCode code = SecKeyChain.Add (record);
if (code == SecStatusCode.DuplicateItem) {
code = SecKeyChain.Remove (existingRec);
if (code == SecStatusCode.Success)
code = SecKeyChain.Add (record);
}
Keychain is a static class with constants so I don't have to retype the strings.
The only thing different between yours and mine is the CreationDate/MatchCaseInsensitive properties and the encoding for NSData. Maybe try it without those and see if it works? If so, add them back separately and see what gives the problem.
This might be because you are running on the simulator - in that case you need to add an Entitlements plist in the project options for your current build config in order to make keychain access work.

Resources