Possibility to modify or extend code in D365FO to suppress thrown error - axapta

Original class function creates an SQL query and executes it.
Since there is an syntax error in the query it throws an error. What's the correct way to achieve fixation? Class extension does not work, because CoC executes the complete original function.
originalFunction(..)
{
createSomeSQLQueryWithSyntayErrorInIt();
executeQuery();
}
The class in question is ReqDemPlanMissingForecastFiller. In method insertMissingDatesForecastEntries a direct SQL statement string is generated. The date variable nonFrozenForecastStartDate is added to the string, but is not escaped correctly as it seems.
If the SQL statement is executed, a syntax error occurs. If the statement is fixed, it can be executed e.g. in SQL Server Management Studio (SSMS).

In this specific case, based on your comments, you may be able to sidestep.
Create a new class ReqDemPlanMissingForecastFiller_Fix extending ReqDemPlanMissingForecastFiller then copy/paste the erroneous function and correct the mistake.
Create an extension class and change the newParameters static funcion.
[ExtensionOf(classStr(ReqDemPlanMissingForecastFiller))]
class ReqDemPlanMissingForecastFiller_Extention
{
public static ReqDemPlanMissingForecastFiller newParameters(
ReqDemPlanCreateForecastDataContract _dataContract,
ReqDemPlanAllocationKeyFilterTmp _allocationKeyFilter,
ReqDemPlanTaskLoggerInterface _logger = null)
{
ReqDemPlanMissingForecastFiller filler = next newParameters(_dataContract, _allocationKeyFilter, _logger);
filler = new ReqDemPlanMissingForecastFiller_Fix(); //Throw away previous value
filler.parmDataContract(_dataContract);
filler.parmAttributeManager(_dataContract.attributeManager());
filler.parmAllocationKeyFilter(_allocationKeyFilter);
filler.parmLogger(_logger);
filler.init();
return filler;
}
}
Code above was based on AX 2012 code. Stupid solution to a stupid problem.
It goes almost without saying that you should report the problem to Microsoft.

#Jan B. Kjeldsen's answer describes how the specific case can be solved without involving Microsoft.
Since overlayering is no longer possible, the solution involves copying a fair bit of standard code. This brings its own risks, because future changes by Microsoft for that code are not reflected in the copied code.
Though it cannot always be avoided, other options should be evaluated first:
As #Jan B. Kjeldsen mentioned, errors in the standard code should be reported to Microsoft (see Get support for Finance and Operations apps or Lifecycle Services (LCS)). This enables them to fix the error.
Pro: No further work needed.
Con: Microsoft may decline the fix or take a long time to implement it.
If unlike in this specific case the issue is not a downright error, but a lack of extension options, an extensibility request can be created with Microsoft. They will then add an extension option.
Pro: No further work needed.
Con: Microsoft may decline the extensibility request or take a long time to implement it.
For both errors as well as missing extension options, Microsoft also offers the Community Driven Engineering program (CDE). This enables you to develop changes in the standard code directly via a special Microsoft hosted repository where the standard code is not locked for changes.
Pro: Most flexible and fastest of all options involving Microsoft.
Con: You have to do the work yourself. Microsoft may decline the change. It can still take some time before the change is available in a GA version.
You can also consider a hybrid approach: For a quick solution, copy standard code and customize it as required. But also report an error, create an extensibility request or fix it yourself in the CDE program. When the change is available in standard code, you can then remove the copied code again.

Related

Why do require to change code runtime?

I found many languages provides some way to change code runtime. Many people ask queries regarding how to change code in this or that language runtime. Here I mean by change code is that rewrite code itself at runtime by using reflection or something else.
I have around 6 year of experience in Java application development. I never come again any problem where I have to change code at time.
Can anyone explain why we require to change code at runtime?
I have experienced three huge benefits of changing code at runtime:
Fixing bugs in a production environment without shutting down the application server. This allowed us to fix bugs on just some part of the application without interrupting the whole system.
Possibility of changing the business rule without having to deploy a new version of the application. A quicker deploy of features.
Writing unit test is easier. For example, you can mock dependencies, add some desired behaviour to some objects and etc. Spock Framework does well this.
Of course, we had this benefits because we have a very well defined development process on how to proceed on this situations.
At times you may need to call a method based on the input, that was received earlier in the program.
It could be used for dynamic calculation of value based on the key index, where every key is calculated in a different way or calculation requires fetching required data from different sources. Instead of using switch statement you can invoke a method dynamically using methodName+indexOfTheKey.

Automate parameter addition to SSRS via asp.net

I am extending an existing app to host SSRS reports with an ASP.Net WebForms ReportViewer control. There are a large number of existing reports. That would not be a problem except that we also need to pass another parameter to each report.
Someone on our team suggested that we might be able to add another parameter and SSRS would pass it along to the stored procedure associated with each report. Not knowing anything about reporting services I looked into it.
I tried the following:
private void AddNewParameter(Report report)
{
var reportParameters = new List<ReportParameter> { new ReportParameter(paramName, "foo", false) };
report.SetParameters(reportParameters);
}
The call Report.SetParameters() complains about the new parameter not existing on the report. The MSDN page for SetParameters() has a note near the bottom that says:
"The parameters specified for the SetParameters method must be defined in the original report definition."
Can anyone confirm the sinking feeling I have that all of our reports must be changed to take the new parameter?
The approach you are attempting is going to be a dead end. Sorry. Sinking feeling is confirmed. However...
If there are a ton of reports then you could probably work out an automated approach to update them all by modifying the underlying Report Definition Language. The link I just posted will take you to the TechNet article that has further links to the actual schema definitions for each version etc.
RDL is really just XML, to quote the TechNet article directly:
RDL is composed of XML elements that match an
XML grammar created for Reporting Services. You can add your own
custom functions for controlling report item values, styles, and
formatting by accessing code assemblies within report definition
files.
Only you could weigh the work of developing this type of solution vs the manual approach.
To get an idea of changes required:
Save copy of one report.
Modify the report with changes
Compare modified rdl to original (BeyondCompare, notepad++, whatever)
If your comfortable with parsing XML, then reproducing the change across remaining reports would be entirely do-able.

Documentation of the lesser know AS3 properties

Over the past three weeks, I have lost at least 120 man hours because of some lesser known functionality in ActionScript 3. One of the problems was that, with Internet Explorer, if there are too many messages sent through LocalConnections, it will slow the messages sent through, but in the standalone player and in Firefox, this threshold is significantly higher. Another was that the static values of a class are instantiated even if the member itself is not being used:
import path.to.FooClass;
private function thisIsNeverCalledButItEnsuresThatFooClassIsImported():void
{
var f:FooClass = new FooClass();
}
Since FooClass had a static reference to a Singleton, that Singleton was instantiated so when I loaded a Module which used that Singleton, it would bind to values in an unpredictable way.
Additional cases where things behave in an unexpected way:
MovieClip.addFrameScript
flash.trace.Trace as a class
int is a faster incrementer class, Number is faster for mathematics, and uint is incredibly slow.
PrintDataGrid, if it has only one page, needs to have an empty value appended to the end of its dataProvider
If you use try...catch around two LocalConnections and connect them to the same channel, you will force garbage collection without needing System.gc
So here's the question (and I'm sorry for omitting this in the original post), is there any consolidated documentation for this type of behavior anywhere? Is there any (even non-Adobe) documentation on these issues (websites, forums, books, ANYTHING)? I know that these things are definitely easy enough TO document, but has anyone done so?
If not, am I missing anything? Are there other issues which I should know about?
This kind of useful information is very often not "centralized". Moreover, what you are looking for is something related to the experience of the programmer (more than to official docs).
FYI, there are two other methods for ensuring a class is included.
#1 - This syntax is actually used in the Flex source code:
import path.to.FooClass; FooClass; // note double reference
public class References
{
// No references needed in this class
}
#2 - Use the includes command line argument
-includes path.to.FooClass
You can always submit your experience using the "feedback" section in the help. Unfortunately, this is less obvious than the link that used to be at the bottom of each page in the older help files (which also served the useful function of opening a browser window with the web version of that help page).
Adobe says that it incorporates the comments from previous versions of the help into new versions, but my own observation suggests that there are instances where it does not happen. However, that and the appropriate cookbook are still the best avenue for those who believe that this kind of information should be centralized.
Note that the whole purpose behind modules is to avoid compiling code multiple times, so importing FooClass kind of defeated the purpose. The problems you had in this instance are just one of the many that happen if you use Singletons, and it's unfortunate that the first official Framework, Cairngorm, encouraged their widespread use. Check out http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/ .

Looking for a simple explanation on using trace logging

I have seen several projects that use the Trace functionality to capture events and stream them out to a log file. I have been unsuccessful in finding a simple to follow guide that will show me how to configure Trace to capture and write said logfile. Does anyone have a link recommendations, or provide some simple steps to follow?
The Trace object writes the statements to any attached TraceListeners. You can build your own, but there are a number already defined in the System.Diagnostics namespace, including:
ConsoleTraceListener (Console)
DefaultTraceListener (Visual Studio / Debugger)
DelimitedListTraceListener (TextWriter, special formatting)
EventLogTraceListener (EventLog - anything that inherits from System.Diagnostics.EventLog)
TextWriterTraceListener (TextWriter - think file)
You can, of course, inherit your own from the TraceListener class that writes to where ever you want. For example, you could log to a database, have it send e-mails or pages in certain situations, or write the statements back to a logging platform like log4net.
The big thing is that you need to create an instance of whatever listeners you want and then add them to the Trace' class Listeners collection. You can add as many as you need and Trace will write to all of them. This way, you can write your logging code once using a well-supported and understood object that's part of the framework, and you can attach anything you need to it.
I stumbled into a MSDN article that really helps. Sorry I didn't find it before posting the question but perhaps others may have the same question and haven't found this link.
Take a look at logging frameworks. We rolled out own, but are now migrating over to log4net available free at http://logging.apache.org/log4net/
Im looking for a way to set the Category of the EventLog, the FormattedEventLogTraceListener writes into (not the category of the message).
But I can't find an appropriate property of this class.
Is it possible to set this?

How can I make my Selenium tests less brittle?

We use Selenium to test the UI layer of our ASP.NET application. Many of the test cases test longer flows that span several pages.
I've found that the tests are very brittle, broken not just by code changes that actually change the pages but also by innocuous refactorings such as renaming a control (since I need to pass the control's clientID to Selenium's Click method, etc) or replacing a gridview with a repeater. As a result I find myself "wasting" time updating string values in my test cases in order to fix broken tests.
Is there a way to write more maintainable Selenium tests? Or a better web UI testing tool?
Edited to add:
Generally the first draft is created by recording a test in the IDE. (This first step may be performed by QA staff.) Then I refactor the generated C# code (extract constants, extract methods for repeated code, maybe repeat the test case with different data, etc). But the general flow of code for each test case remains reasonably close to the originally generated code.
I've found PageObject pattern very helpful.
http://code.google.com/p/webdriver/wiki/PageObjects
more info:
- What's the Point of Selenium?
- Selenium Critique
maybe a good way to start is to incrementally refactor your test cases.
I use the same scenario you have selenium + c#
Here is how my code looks like:
A test method will look like somethink like this
[TestMethod]
public void RegisterSpecialist(UserInfo usrInfo, CompanyInfo companyInfo)
{
var RegistrationPage = new PublicRegistrationPage(selenium)
.FillUserInfo(usrInfo)
.ContinueSecondStep();
RegistrationPage.FillCompanyInfo(companyInfo).ContinueLastStep();
RegistrationPage.FillSecurityInformation(usrInfo).ContinueFinishLastStep();
Assert.IsTrue(RegistrationPage.VerifySpecialistRegistrationMessagePayPal());
selenium.WaitForPageToLoad(Resources.GlobalResources.TimeOut);
paypal.LoginSandboxPage(usrInfo.sandboxaccount, usrInfo.sandboxpwd);
Assert.IsTrue(paypal.VerifyAmount(usrInfo));
paypal.SubmitPayment();
RegistrationPage.GetSpecialistInformation(usrInfo);
var bphome = new BPHomePage(selenium, string.Format(Resources.GlobalResources.LoginBPHomePage, usrInfo.AccountName, usrInfo.Password));
Assert.IsTrue(bphome.VerifyPageWasLoaded(usrInfo));
Assert.IsTrue(bphome.VerifySpecialistProfile());
bphome.Logout();
}
A page Object will be something like this
public class PublicRegistrationPage
{
public ISelenium selenium { get; set; }
#region Constructors
public PublicRegistrationPage(ISelenium sel)
{
selenium = sel;
selenium.Open(Resources.GlobalResources.PublicRegisterURL);
}
#endregion
#region Methods
public PublicRegistrationPage FillUserInfo(UserInfo usr)
{
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserFirstName", usr.FirstName);
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserLastName", usr.LastName);
selenium.Select("ctl00_cphComponent_ctlContent_wizRegister_ddlUserCountry", string.Format("label={0}",usr.Country ));
selenium.WaitForPageToLoad(Resources.GlobalResources.TimeOut);
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserEmail", usr.Email );
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserDirectTel", usr.DirectTel);
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserMobile", usr.Mobile);
return this;
}
}
Hope this helps.
How are you creating your Selenium tests, by recording them and playing them back? What we have done is build an object model around pages so that you call a method like "clickSubmit()" rather than clicking on an id (with a naming convention for these ids), which allows selenium tests to survive many changes.
You may or may not be able to write tests that are resilient to refactoring. Here's how to make the refactoring less painful: Continuous integration is essential.
Run them every day or every build. The sooner it's fixed, the easier.
Ensure devs can run the tests themselves. Again, the sooner it's seen and fixed, the easier.
Keep selenium tests few. They should focus on critical path / pri 1 test scenarios. Deep testing should be done at unit test level (or jsunit tests). Integration tests are always expensive and less valuable.
Hooking up on any low-level concepts like XPaths, CSS Selectors or IDs for end-to-end tests is a recipe for unstable tests.
I advise using testRigor to produce tests that won't break any time you run/change/improve your application a little bit.
The code analogous to the page object one above would look like this:
enter "Peter" into "First Name"
enter "Pen" into "Last Name"
enter "US" into "Country" below "User Data"
enter stored value "email" into "Email"
enter stored value "password" into "Password"
enter "415-123-4567" into "Direct Telephone"
enter "415-123-4568" into "Mobile Number"
click "Submit"
testRigor would associate texts that look like labels with the inputs so that as soon as from an end-user's perspective your page would look the same then the testRigor scripts will be green. Here is the doc.
disclaimer: I'm a co-founder of testRigor. I co-founded it because we had those exact issues ourselves.
Hope this helps.
There are no innocuous changes when it comes to test automation ;)
We use the SAFS framework with Rational Robot (RRAFS) to minimize impact to our automation scripts. There's still work to maintain the application map, but the scripts remain stable for the most part. The SAFS framework sounds very similar to the method cynicalman mentions, but already packages up the generic methods you would use in your scripts.
The SAFS site says there's partial support for Selenium, so this may work for you.
I've found that using XPath expressions in Selenuium-RC adds alot to the robustness of a test.
I write my tests in a similar manner. The first pass is often written via the IDE/Record to get most of my page-flow and click operations. Once I've got that, I begin stepping through the test via Selenium-RC adding assertions and changing absolute widget locators to more readable and friendly Xpath expressions. (as well as documenting the test! :) )
One thing to be aware of.. if your tests are xpath-heavy, they may run a little slower in IE6 due to its poor javascript execution abilities. (I have some test suites that take almost an hour longer to execute under IE than under FF. It's managable, but just something to keep in mind when you're writing the tests.)
Selenium in theory has an abstraction called UI Element (the documentation is here).
The features would be
abstract locators, indipendent on the very html implementation; this would map well to the concept of component or widget of a web framework,
rollup rules, allowing to merge several commands into a single more abstract command.
I've struggled a couple of days to leverage this feature but in the end I decided to abandon it, for the following reasons:
some concepts, such as that of offset locators (think of them as parts of a component) are not fully or usefully developed;
the feature is not fully supported in formatters and the more recent the formatter the less the feature is supported, hinting that the core Selenium evolution is leaving this feature behind;
it's not fully integrated in Selenium 2.0 (WebDriver).
I think Xpath is the best way to ensure robust selenium tests.
I am currently working on a library to help writing xpath expressions easier.
If interested, you can check it out here:
http://www.unit-testing.net/CurrentArticle/How-To-Write-XPath-for-Selenium-Tests.html

Resources