Why is the company's document management system difficult to maintain, even ASP. NET programmers who have been working for many years think so?

Source: Internet
Author: User

After years of development, the company has a complete document management system. At the beginning, PHP was designed. Net was gradually switched to. Net for rewriting. After years of maintenance and development (n> 10), there are now a large number of customers and their functions are complete. Recently, some tasks are to modify the system, hide some controls, and modify some la s, which is easy at first. However, as the task progresses, a small function is found to be modified, it is also quite troublesome.
For example, to modify a control, set it to hide or display according to different read parameters.
For example, when the user enablesimpleui is set to true, the remarks control is hidden and does not need to be displayed. The description control is defined as follows:
<Asp: textbox id = "txtremard" textmode = "multiline" length = "200">
The job I want to do is to read the value of enablesimpleui IN THE page_init () method and set the txtremard. visible attribute based on it.
However, the workload is far from that easy. Let me list why it is not easy to maintain.

1 Interface Code Obfuscation with business logic

I didn't mean to criticize this. The separation between the interface and the Business Code is also relative, and it cannot be completely 100% isolated. For winformsProgramBy using debug, you can find every place where the control properties are modified and modify them one by one. However, if it is an ASP. NET program, the interface code is confused with the business logic. The interface layout relies heavily on JavaScript function settings. Such layout brings great trouble to maintenance personnel.
First, let's take a look at its interface layout, which is effective in the design view of Visual Studio 2008.

All controls are designed according to the predefined layout, and only HTML controls are available. ASP. NET Server-side controls are not used. Their explanatory text is dynamically generated. For example, the butten text is passed in by the ASP. NET background code.

<Input type = "button" value = "<% = rstr (1306058) %>" onclick = "addattindex (this. Form)">
The tag control is written in this way.
<% = Rstr (1306011) %>: <input type = "text" name = "attachmentdescription" id = "attachmentdescription"/>
This is not complicated yet. The complicated problem is that JavaScript scripts are confused with C # code.
<SCRIPT lang = "JavaScript">
VaR enablesimpleui = <% = enablesimpleui %>; this is a global variable of JavaScript and gets the value from the background code.
Obfuscation between C # code and JavaScript code like the following

<% IF (issupportscope) {%>
Form. docclassshared. value = "0 ";
<% }%>
Form. docclassforcever. value = "0 ";
Docclassforcever is a hidden variable defined on the page. Its initial values are obtained from the C # code and then used on the ASPX page.
<Input type = "hidden" name = "docclassshared" value = "<% # doctypeshared %>">

This reminds me of the time when ASP was used as a small business website when I graduated. No obvious background code exists in ASP. For ASP pages that only contain VB script code, but do not contain HTML control interfaces, they can be regarded as background code. Then, they can use # include to nest several pages and background code, this is a typical mode of ASP development. Therefore, I always think that this is the development mode of ASP, the. NET language for web projects, it is not easy to maintain.

 

2. Code duplication is serious

Let's take a look at the repeated code in C # and the repeated code.

Public partial class doctype_addpage: system. Web. UI. Page
{

Private string defaultdate = "yyyy-mm-dd ";

Override protected void oninit (eventargs E)
{
_ Commonhelper = new common (Session, response, request, cache );
}

Protected void page_error (Object sender, eventargs E)
{

System. Exception serverexception;
Serverexception = server. getlasterror ();
If (serverexception! = NULL)
{
Errmsg = serverexception. message;
Server. clearerror ();
}
}

Protected void page_load (Object sender, system. eventargs E)
{

Utility. Setting setting = new utility. Setting ();
Setting. initialize (false );
}
Repeated code analysis

1) The defaultdate variable may be used to set the date format. If it is not a special requirement, the variable value should be placed in common settings, to ensure that the default date format for each page is yyyy-mm-dd.

2) In page_load, the setting object will be created every time the page is PostBack. It should be placed in if (! Page. ispostback) clause.
3) oninit creates a common configuration information reading object. When page_error occurs, record the error and clear the error, redirect the page to the error display page, and page_load loads public configuration items, these three functions require such processing for all pages. In my opinion, we should design pagebase pages and put the functional code of these three methods into pagebase to reduce duplication.


The javascript code is repeated. One advantage of JavaScript is that it can directly operate interface controls in the DOM mode, which is also a disadvantage. This will lead to many JavaScript code repetition, because developers are temporarily lazy, he does not want to extract the code that can solve the problem into the common JavaScript library method, reducing the time for writing tests and parameter descriptions, in exchange for future maintenance costs. Too many repeated JavaScript codes cannot be computed.

VaR OBJ = thisform. docattrclasstype
VaR TMP = new array ();
For (VAR I = 0; I <obj. Options. length; I ++)

{
VaR Ops = new op ();
Ops. _ value = obj. Options [I]. value;
Ops. _ text = obj. Options [I]. text;
TMP. Push (OPS );

}
TMP. Sort (sortrule );
For (var j = 0; j <TMP. length; j ++)

{
OBJ. Options [J]. value = TMP [J]. _ value;
OBJ. Options [J]. Text = TMP [J]. _ text;

}

These statements can be extracted into a common method, which clears the items in ListBox/option, sorts them, and adds them again. If you add these two sentences
Thisform. docattrclasstype. selectedindex = 0;
Thisform. docattrclasstype. Disabled = false;
This suddenly becomes a specific method, only applicable to thisform. docattrclasstype objects.
Javascript really requires a public class library, so jquery is very popular and then directly integrated into ASP. NET. To reduce the Code maintained in the future, I think it is necessary to select a mature JavaScript class library.

 

3. Some unnecessary code exists.

Take the reading/writing class of the database table document as an example.

Public class document: idocumentaddon
{
Private sqlconnection localdbconn;
Private bool localdbconninit;
Private sqltransaction localdbtran;
Private bool localdbtraninit;

Public document (string connectionstring ){}
Public bool dispose ()
Take the user table of the database as an example.

Public class user: iuser
{
Protected sqlconnection localdbconn;
Protected bool localdbconninit;
Protected sqltransaction localdbtran;
Protected bool localdbtraninit;

Public user (string connectionstring ){}
Public bool dispose ()

Each data table read/write class uses the complete ADO. Net code to read and write the database internally. The following code is used as an example:
String querystring = "select orderid, customerid from DBO. Orders ;";
Using (sqlconnection connection = new sqlconnection (connectionstring ))
{
Sqlcommand command = new sqlcommand (querystring, connection );
Connection. open ();
Sqldatareader reader = command. executereader ();
Try {While (reader. Read ())
{
Console. writeline (string. Format ("{0}, {1}", reader [0], reader [1]);}
}
Finally {reader. Close ();}
}
Each CRUD operation is encapsulated in such a statement block, which leads to a large amount of unnecessary code. Take the enterprise database as an Example
Enterpriselibraryshared. connectonstring = "Server = (local); database = northwind; uid = sa; Pwd = 123456 ";

Database m_commondb;
String sqlget_shiftcodelist = @ "select * From DBO. MERs ";

M_commondb = databasefactory. createdatabase ();
Dbcommand cmd = m_commondb.getsqlstringcommand (sqlget_shiftcodelist );
Dataset dsshiftcode = m_commondb.executedataset (CMD );
Put the above standard ADO. net code is replaced by the call method of the Enterprise Library, the code will be much simpler, and there is a data access bug is also easy to find the problem, just need to debug the Enterprise Library ADO. net code.

4. Manually splice SQL statements

Take SQL as an example, select orderid, customerid from DBO. Orders, and read the Order Number and customer number.
Now you need to maintain the system and add a control point enablecustomervisible to control whether to display the customer code. After repeated explanations in the previous article, the control bound to the database is first hidden, and finally the SQL statement is modified to not read the customer number.
Select orderid from DBO. Orders,

If the SQL statement of the program is written together, modify the SQL statement for each order to avoid reading the customer number.
If you have a code generator, as shown below, you can remove the check mark before the client code and re-generate the crud C # code.


If you use an ORM to read and write the database, use llbl Gen as an example.

Excludeincludefieldslist excludedfields = new excludeincludefieldslist ();

Excludedfields. Add (customerfields. orderid );
If (enablecustomervisible)

Excludedfields. Add (customerfields. customerid );

Customersentity c = new customersentity ("chops ");

Dataaccessadapter adapter = new dataaccessadapter ())

Adapter. fetchentity (C, null, null, excludedfields );
When the enablecustomervisible condition is false, the value of the customerid field is not read.
The conclusion is that, in order to facilitate future maintenance, we should try to use the SQL patchwork method as little as possible. Even if you want to use it, you 'd better work with the code generator to help generate code.

 

5 multi-language solutions increase the complexity of interface Maintenance

ASP. NET 2.0 provides many technical solutions, such as themes, multiple languages, and data source controls. However, before ASP. NET 2.0 was launched, most companies had already prepared their own multilingual solutions, which won't be easily changed during the maintenance and upgrade process. Take the document system as an example

<% = Rstr (1306011) %>: <input type = "text" name = "attachmentdescription" id = "attachmentdescription"/>
Call the method rstr where the label is needed, and input the parameter value to it. Call the following method in the background to obtain the value from the database.

Lbl_desc5 = _ commonhelper. getlocalizedtext (1306011 );
This solution is common and is not worth mentioning. With the customization requirements of customers, I have the advantage of multiple languages. Customers usually have special requirements on the label name. If it is written to the label, you usually need to modify the page file. However, if you have a multilingual interface scheme, you can directly modify the description corresponding to the key value to modify the name. This is an additional benefit I have discovered to implement a multi-language solution.
It is also quite obvious that the multi-language scheme causes the interface layout to be unable to easily view and modify the specified control in the design view during design, which is a disadvantage, if a div is hidden, it needs to be dynamically displayed or hidden, but the design view interface does not have any prompts, which will also lead to increased maintenance complexity.

 

6. Sample and document are missing for the referenced third-party class libraries

If you want to reference a third-party Type Library in the project, I think it is necessary to create a document folder and put the sample and document here for future maintenance. It may take a long time for a project, but you may not always find the right information on the Internet to help you solve the problem. The old system does not always get a budget, but it can be rewritten, and it can be a huge boost. This idea is usually not feasible. The developer at the beginning can clearly understand the third-party components used by the developer, but the maintenance will not be so easy in the future. If no help information is found, debugging and tracing at the source code level is equivalent to that at the source code level of a third-party component.Source codeAnd decompile it out, and then follow up debugging. This will be more troublesome. If a third-party library is encrypted to prevent decompilation, this will be even worse. Therefore, my idea is to carefully reference a third-party Type Library and try to use a common Microsoft type, which will bring convenience to maintenance.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.