How to get report bytes in 21.208 - acumatica

I have the following code in a 2020 R1 system that I am trying to upgrade to 21.208. The problem is that the "SettingsProvider" does not have an "Instance" property so, this is causing a build error. Also, I'm getting warnings that the PXReportTools is obsolete but, I'm not sure what to replace it with?
This code is to get the byte[] of a report and then attach it to an email. What is the newer 21.208 way to do this?
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary["ARInvoice.DocType"] = current.DocType;
dictionary["ARInvoice.RefNbr"] = current.RefNbr;
Report report = PXReportTools.LoadReport("AR641000", (IPXResultset)null);
PXReportTools.InitReportParameters(report, (IDictionary<string, string>)dictionary, SettingsProvider.Instance.Default);
byte[] data = PX.Reports.Mail.Message.GenerateReport((object)ReportProcessor.ProcessReport(report), "PDF").First<byte[]>();
TIA!

As of 21R2 for report loading you need to import two dependencies in your graph using dependency injection
[InjectDependency]
protected IReportLoaderService ReportLoader { get; private set; }
[InjectDependency]
protected IReportRenderer ReportRenderer { get; private set; }
Then using this two services you can retrieve the byte report data using the following:
Dictionary<String, String> parameters = new Dictionary<String, String>();
Report _report = reportLoader.LoadReport(ARReports.InvoiceMemoReportID, null);
reportLoader.InitDefaultReportParameters(_report, parameters);
byte[] fileDate = null;
using (StreamManager streamMgr = new StreamManager())
{
reportRenderer.Render(RenderType.FilterPdf, _report, deviceInfo: null, streamMgr);
fileData = streamMgr.MainStream.GetBytes();
}
You can also save it in a FileInfo Object if you want to save it locally with a name.

Related

Spring integeration DefaultSoapHeaderMapper - getStandardRequestHeaderNames - override

in previous si versions (si 2.11 to be specific and spring 3.1.1) getStandardRequestHeaderNames could be overrided to include Additional Application specific objects in the si message header. Our application relied on this ability (may be wrongfully so) to override this method and supply a custom POJO to be carried downstream consisting of many splitters, aggregators etc. The app used an ws inbound gateway and used the header-mapper attribute to specify the custom soap header mapper.
Any clues on the reasoning behind why getStandardRequestHeaderNames cannot be overriden?
Need some advise on how I can migrate this to the current spring release.
The requirement is to extract elements from soapHeader and map them to an SI message headers as an POJO and send it down stream.
All help appreciated.
Code Snippet: Works with older versions of spring
<int-ws:inbound-gateway id="webservice-inbound-gateway"
request-channel="input-request-channel"
reply-channel="output-response-channel"
header-mapper="CustomSoapHeaderMapper"
marshaller="marshaller"
unmarshaller="marshaller" />
#Component("CustomSoapHeaderMapper")
public class CustomSoapHeaderMapper extends DefaultSoapHeaderMapper {
private static final Logger logger = Logger.getLogger("CustomSoapHeaderMapper");
public static final String HEADER_SEARCH_METADATA = SearchMetadata.HEADER_ATTRIBUTE_NAME;
public static final String HEADER_SERVICE_AUDIT = "XXXXXXXX";
// Use simulation if security token is set to this value
public static final String SECURITY_TOKEN_SIMULATION = "XXXX";
private static final List<String> CUSTOM_HEADER_NAMES = new ArrayList<String>();
static {
CUSTOM_HEADER_NAMES.add(WebServiceHeaders.SOAP_ACTION);
CUSTOM_HEADER_NAMES.add(HEADER_SEARCH_METADATA);
}
private int version =SearchMetadata.VERSION_CURRENT;
public void setVersion(int version) {
this.version = version;
}
#Override
protected List<String> getStandardRequestHeaderNames() {
return CUSTOM_HEADER_NAMES;
}
#Override
protected Map<String, Object> extractUserDefinedHeaders(SoapMessage source) {
// logger.log(Level.INFO,"extractUserDefinedHeaders");
// call base class to extract header
Map<String, Object> map = super.extractUserDefinedHeaders(source);
Document doc = source.getDocument();
SearchMetadata searchMetadata = new SearchMetadata();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
source.writeTo(baos);
baos.flush();
searchMetadata.setRequestXML(baos.toString());
baos.close();
} catch (IOException e1) {
}
//logger.log(Level.WARNING, "Incoming Message " + baos.toString());
SOAPMessage soapMessage = ((SaajSoapMessage) source).getSaajMessage();
// generate TransactionID with UUID value
String transactionID = UUID.randomUUID().toString();
// logger.log(Level.WARNING, "TransactionID=" + transactionID);
Date now = new Date();
searchMetadata.setTransactionID(transactionID);
searchMetadata.setRequestType(SearchMetadata.REQUEST_TYPE_SYNCHRONOUS);
searchMetadata.setRequestTime(now);// initialize the request time
searchMetadata.setReceivedTime(now);// mark time system receives request
searchMetadata.setVersion(version);
Map<String, Object> finalHeaders = new HashMap<String, Object>();
finalHeaders.put(HEADER_SEARCH_METADATA, searchMetadata);
if (!CollectionUtils.isEmpty(map)) {
// copy from other map
finalHeaders.putAll(map);
// check if ServiceAudit is available
SoapHeaderElement serviceAuditElement = null;
for (String key : map.keySet()) {
// logger.log(Level.WARNING, "SoapHeader.{0}", key);
if (StringUtils.contains(key, HEADER_SERVICE_AUDIT)) {
serviceAuditElement = (SoapHeaderElement) map.get(key);
break;
}
}
}
return finalHeaders;
}
// GK Key Thing here for performance improvement is avoiding marshalling
public gov.dhs.ice.ess.schema.ServiceAudit ExtractAuditHeader(Document doc) {
....
}
return serviceAudit;
}
}
Share, please, some code how would you like to see that.
Maybe you can just implement your own SoapHeaderMapper and inject it into WS Inbound Gateway?
You can still reuse your logic and copy/paste the standard behavior from the DefaultSoapHeaderMapper.
UPDATE
The test-case to demonstrate how to add user-defined header manually:
#Test
public void testCustomSoapHeaderMapper() {
DefaultSoapHeaderMapper mapper = new DefaultSoapHeaderMapper() {
#Override
protected Map<String, Object> extractUserDefinedHeaders(SoapMessage source) {
Map<String, Object> headers = super.extractUserDefinedHeaders(source);
headers.put("foo", "bar");
return headers;
}
};
mapper.setRequestHeaderNames("*");
SoapMessage soapMessage = mock(SoapMessage.class);
Map<String, Object> headers = mapper.toHeadersFromRequest(soapMessage);
assertTrue(headers.containsKey("foo"));
assertEquals("bar", headers.get("foo"));
}

Save httppostedfilebase as image in SQL

I have a situation where I am getting an image as httppostedfilebase type in my MVC code. I have a corresponding Image type column in my SQL db.
I need to know how do I convert/Save this httppostedfilebase type as image in my DB.
Create a function to convert HttpPostedFileBase object to file
public byte[] ConvertToByte(HttpPostedFileBase file)
{
byte[] imageByte = null;
BinaryReader rdr = new BinaryReader(file.InputStream);
imageByte = rdr.ReadBytes((int)file.ContentLength);
return imageByte;
}
Code like this in Your Controller
public ActionResult Create(AdminDetailsViewModel viewmodel)
{
if (ModelState.IsValid)
{
HttpPostedFileBase file = Request.Files["ImageData"];
viewmodel.Image = ConvertToByte(file);
db.YourDbContextSet.Add(viewmodel);
db.SaveChanges();
}
}
Hope this will help

Unable to Serialize into XML

I am trying to Serialize the content of some text into an XML file (performed when a user saves their selections), and then will later deserialize it (when the user chooses to display their saved selection).
I have been following the following tutorial on serialization.
I have also tried to do this via LINQ to XML but was either getting namespace errors, or the tool returned no errors, but did not work (with the same problem as described below).
The problem I am having is that my code is not returning any errors, but the function is not working (I have a label control that allows me to see that the 'catch' is being returned). I am building the tool in Expression Blend, using C#.
Here is my SaveSelection.cs Class
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml.Serialization;
using System.Xml;
namespace DYH
{
public class SaveSelections
{
[XmlAttribute("Title")]
public string Title
{ get; set; }
[XmlElement("Roof")]
public string RoofSelection
{ get; set; }
[XmlElement("Cladding")]
public string CladdingSelection
{ get; set; }
[XmlElement("MixedCladding")]
public string MixedCladdingSelection
{ get; set; }
[XmlElement("FAJ")]
public string FAJSelection
{ get; set; }
[XmlElement("GarageDoor")]
public string GarageDoorSelection
{ get; set; }
[XmlElement("FrontDoor")]
public string FrontDoorSelection
{ get; set; }
}
}
Here is my C# code
// Save Selection Button
private void Button_SaveSelection_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
try
{
// Save selections into the SavedSelections.xml doc
SaveSelections userselection = new SaveSelections();
userselection.Title = TextBox_SaveSelection.Text;
userselection.RoofSelection = Button_Roof_Select.Text;
userselection.CladdingSelection = Button_Cladding_Select.Text;
userselection.MixedCladdingSelection = Button_MixedCladding_Select.Text;
userselection.FAJSelection = Button_FAJ_Select.Text;
userselection.GarageDoorSelection = Button_GarageDoor_Select.Text;
userselection.FrontDoorSelection = Button_FrontDoor_Select.Text;
SerializeToXML(userselection);
// XDocument xmlSaveSelections = XDocument.Load("../SavedSelections.xml");
//
// XElement newSelection = new XElement("Selection", //xmlSaveSelections.Element("Selections").Add(
// //new XElement("Selection",
// new XElement("Title", TextBox_SaveSelection.Text),
// new XElement("RoofSelection", Button_Roof_Select.Text),
// new XElement("CladdingSelection", Button_Cladding_Select.Text),
// new XElement("MixedCladdingSelection", Button_MixedCladding_Select.Text),
// new XElement("FAJSelection", Button_FAJ_Select.Text),
// new XElement("GarageDoorSelection", Button_GarageDoor_Select.Text),
// new XElement("FrontDoorSelection", Button_FrontDoor_Select.Text));
//
//// xmlSaveSelections.Add(newSelection);
//// xmlSaveSelections.Save("../SavedSelections.xml");
SelectionLabel.Text = "Your selection has been saved as " + "'" + TextBox_SaveSelection.Text + "'. We suggest you write down the name of your selection.";
}
catch(Exception ex)
{
throw ex;
SelectionLabel.Text = "There was a problem saving your selection. Please try again shortly.";
}
}
// Saves SaveSelection.cs to XML file SavedSelections.xml
static public void SerializeToXML(SaveSelections selection)
{
XmlSerializer serializer = new XmlSerializer(typeof(SaveSelections));
TextWriter textWriter = new StreamWriter(#"/SavedSelections.xml");
serializer.Serialize(textWriter, selection);
textWriter.Close();
}
I have left evidence of one of my previous attempts commented out so you can see a previous format I tried.
My issue is that when I try to use the tool, the SelectionLabel.Text returns "There was a problem saving your selection. Please try again shortly." so I know that the code is returning the catch and not executing the 'try'.
Any help??
Edit 18/6/2012: The below code was the code that worked as per correct answer to question.
public void Button_SaveSelection_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
string roofSelection = TextBox_SaveSelection.Text + "_RoofSelection";
string claddingSelection = TextBox_SaveSelection.Text + "_CladdingSelection";
string mixedCladdingSelection = TextBox_SaveSelection.Text + "_MixedCladdingSelection";
string fajSelection = TextBox_SaveSelection.Text + "_FAJSelection";
string garageDoorSelection = TextBox_SaveSelection.Text + "_GarageDoorSelection";
string frontDoorSelection = TextBox_SaveSelection.Text + "_FrontDoorSelection";
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
// Gives us 6Mb of storage space in IsoStore
Int64 isoSpaceNeeded = 1048576 * 6;
Int64 currentIsoSpace = store.AvailableFreeSpace;
// If space needed is greater than (>) space available, increase space
if (isoSpaceNeeded > currentIsoSpace)
{
// If user accepts space increase
if (store.IncreaseQuotaTo(currentIsoSpace + isoSpaceNeeded))
{
IsolatedStorageFileStream file = store.CreateFile("SavedSelections.txt");
file.Close();
// Stream writer to populate information in
using (StreamWriter sw = new StreamWriter(store.OpenFile("SavedSelections.txt", FileMode.Open, FileAccess.Write)))
{
appSettings.Add(roofSelection, Button_Roof_Select.Text);
sw.WriteLine(roofSelection);
appSettings.Add(claddingSelection, Button_Cladding_Select.Text);
sw.WriteLine(claddingSelection);
appSettings.Add(mixedCladdingSelection, Button_MixedCladding_Select.Text);
sw.WriteLine(mixedCladdingSelection);
appSettings.Add(fajSelection, Button_FAJ_Select.Text);
sw.WriteLine(fajSelection);
appSettings.Add(garageDoorSelection, Button_GarageDoor_Select.Text);
sw.WriteLine(garageDoorSelection);
appSettings.Add(frontDoorSelection, Button_FrontDoor_Select.Text);
sw.WriteLine(frontDoorSelection);
}
SelectionLabel.Text = "Your selection has been saved as " + "'" + TextBox_SaveSelection.Text + "'. We suggest you write down the name of your selection.";
}
}
}
SelectionLabel.Text = "Your selection has been saved as " + "'" + TextBox_SaveSelection.Text + "'. We suggest you write down the name of your selection.";
}
catch //(Exception ex)
{
//throw ex;
SelectionLabel.Text = "There was a problem saving your selection. Please try again shortly.";
}
}
It looks like your issue is because you're trying to a file, but that file did not come from a FileSaveDialog initiated by a user action. You're running into a security feature of Silverlight where you're not allowed access to the local file system. Instead, try writing to IsolatedStorage. However, be aware that end users can completely (as well as selectively) disable application storage so you'll need to handle those exceptions as well.
Here's a quick article on how to use IsolatedStorage.

Sharepoint search fails when using DataKeynames

We have a Sharepoint site which uses search.
We get the following error:
Unable to validate data. at
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData
(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length,
IVType ivType, Boolean useValidationSymAlgo)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
After a bit of testing we have found that the error occurs when we use DateKeyNames on a GridView control.
Not sure why there should be any combination between Search, this error and DataKeyNames.
Any ideas?
Update: Here is some code
[Guid("8891224e-e830-4ffa-afbd-f789583d8d14")]
public class TestErrorGridView : System.Web.UI.WebControls.WebParts.WebPart
{
Control ascxToAdd;
public TestErrorGridView()
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
protected override void CreateChildControls()
{
base.CreateChildControls();
Table test = new Table();
TestBindObject t1 = new TestBindObject() { ID = 1, Name = "Test" };
List<TestBindObject> l1 = new List<TestBindObject>();
l1.Add(t1);
SPGridView testGrid = new SPGridView() { AutoGenerateColumns = false};
BoundField header = new BoundField();
header.DataField = "ID";
BoundField name = new BoundField();
name.DataField = "Name";
testGrid.Columns.Add(header);
testGrid.Columns.Add(name);
testGrid.DataSource = l1;
testGrid.DataBind();
// If you comment out this line search works
testGrid.DataKeyNames = new string[] { "ID" };
this.Controls.Add(testGrid);
base.CreateChildControls();
SPGridView testGrid = new SPGridView() { AutoGenerateColumns = false, EnableViewState=false };
testGrid.DataKeyNames = new string[] { "testid" };
this.Controls.Add(testGrid);
}
}
public class TestBindObject
{
public int ID { get; set; }
public string Name { get; set; }
}
UPDATE
This error occurrs on the developer machines, so it is not realated to machine keys being different on different machines in a cluster.
One of the developers has MOSS installed, he does not get the error. The developers who have just WSS installed get the error.
UPDATE 2
Have added datasource to code
I'm going to throw out a guess here since the code where you set the GridView's datasource is missing as well, but here goes...
It probably has something to do with the order in which you are setting the GridView's properties. My guess is that you need to set it in this order:
Create your GridView
Set the GridView's datasource (so that it has data)
Set DataKeyNames
Call GridView.DataBind()
Step 3 and 4 are the steps I am not sure about. You may have to DataBind and then set DataKeyNames.
We eventually solved this by following the example in this link:
http://msdn.microsoft.com/en-us/library/bb466219.aspx
I think that is was binding to a data table rather than a list that made the difference.
The fact that Sharepoint grids do not allow autogenerated columns appears to be one of the factors leading to this problem.

SharePoint 2007 (wss) search and Unable to validate data Exception

We have a problem with SharePoint's search box. Whenever we try to search for something we get:
Unable to validate data. at
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean
fEncrypt, Byte[] buf, Byte[] modifier,
Int32 start, Int32 length, IVType
ivType, Boolean useValidationSymAlgo)
at
System.Web.UI.ObjectStateFormatter.Deserialize(String
inputString) exeption.
Does any one know the reason for this exception, or a way to work around it?
New entry:
I'm using a SPGridView where i use the datakeys property in a web part. The webpart works, but we found that using the datakeys property breaks seach in that if you try to use the search textbox and click the seach button it gets this exception:
Unable to validate data. at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
This is what i have tryed to do:
Make the gridview not spgridview and set autogenerate true (works)
Remove the datakeynames (works)
Test with a empty gridvew (failes)
Test with a non-empty gridview (failes)
Change Machine Keys (failes)
Turn of view state on the gridvew (failes)
Move the gridview ti a ascx file (failes)
I can't seem to figure this one out. Have enyone got this error and been able to work around it?
EDit 10.09.2009
This is the last code I tested. I used a MSDN excample as referance. I have also tried without Data table MSDN Example
public class TestErrorGridView : System.Web.UI.WebControls.WebParts.WebPart
{
Control ascxToAdd;
protected DataTable PropertyCollection = new DataTable();
private DataColumn key;
public TestErrorGridView()
{
key = PropertyCollection.Columns.Add("ID", typeof(string));
PropertyCollection.Columns.Add("Name", typeof(string));
}
public void AddProperty(TestBindObject data)
{
DataRow newRow = PropertyCollection.Rows.Add();
newRow["ID "] = data.ID;
newRow["Name"] = data.Name;
}
public void BindGrid(SPGridView grid)
{
SPBoundField fldPropertyName = new SPBoundField();
fldPropertyName.HeaderText = "ID";
fldPropertyName.DataField = "ID";
grid.Columns.Add(fldPropertyName);
SPBoundField fldPropertyValue = new SPBoundField();
fldPropertyValue.HeaderText = "Name";
fldPropertyValue.DataField = "Name";
grid.Columns.Add(fldPropertyValue);
PropertyCollection.PrimaryKey = new DataColumn[] { key };
grid.DataSource = PropertyCollection.DefaultView;
grid.DataKeyNames = new string[] { key.ColumnName };
grid.DataBind();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
protected override void CreateChildControls()
{
base.CreateChildControls();
TestBindObject t1 = new TestBindObject() { ID = 1, Name = "Test3" };
this.AddProperty(t1);
SPGridView testGrid = new SPGridView() { AutoGenerateColumns = false };
this.BindGrid(testGrid);
this.Controls.Add(testGrid);
}
}
[Serializable]
public class TestBindObject
{
public int ID { get; set; }
public string Name { get; set; }
}
From the error message I'd say that you are operating in a web-farm environment. Have you set the same machineKey in each of the SharePoint web.config files? See this link for a little more info.

Resources