公司需要开发一款档案管理系统,由于人手不足,我只能自己开发,由于是公司内部使用,所以开发也是尽量功能与界面简洁简单为主,但依旧免不了开发过程中遇到许多奇怪的问题,现在开发完了,回忆一下当初的一些经验教训,希望能给相同境遇的开发者一些方法上的帮助。
一,ajax方法的运用
ajax方法在这里帮助了我很多,之前一直不重视前台有三个下拉列表,除了第一个下拉列表直接读取数据库内容以外,剩下的两个都需要前一个的选择进行判定显示内容,这个时候用了ajax和json的传值,后台处理之后用Session或者ViewData等在前台将后台处理的前台代码显示,只是有个缺点,就是这样会导致后台写大量的前台代码需要HtmlString去解析,而且ajax属于异步操作,显示内容在前台无法用F12查看到,所以调试的时候十分不方便,需要在前台把代码写好之后复制到后台。
在这里我附上一个例子详细记录一下用到的内容。
function hhh() {
var sel = document.getElementById("JK");
var index = sel.selectedIndex;
var results = sel.options[index].text;
$.ajax({
type: "post",
url: "RefreshAnjuan",
data: { AnjuanInstitution: JSON.stringify(results) },
datatype: "string",//json
success: function (data) {
// alert("新增" + data + "成功");
$("#AJ").html(data);//这几天就栽在这短短的一个语句上了。只有这句才可以局部刷新,写入新内容。
$("#FL").html("<option></option>");
},
Error: function (data) {
// alert("新增" + data + "失败");
}
})
}
函数内的前三行是取值的内容,第四行之后是ajax的代码,type代表类型是post,url填写的是数据传递的后台函数名,data内,举个例子左边是传值到的方法内的Request[“AnjuanInstitution”]中取值,右边意思是将results这个值用Json传递,results就是我们在前台取到的值,然后通过Json方法告诉后台,我要存到AnjuanInstitution中,你需要Request[“AnjuanInstitution”]接收。
然后success就是传值成功后,如果后台函数时string等可以返回数据的类型return了一个数据,这个值会通过data(function里面的)传回前台处理。
后台代码如下,仅供参考:
public string RefreshAnjuan()//查询页面根据卷库显示案卷
{
var test = Request["AnjuanInstitution"];
var test2 = test.ToString();
string[] arry = test.ToString().Split(new char[2] { '/', '"' });//这个地方很神奇,明明是“\”却用“/”达到了效果
string result = arry[1].ToString();
LinqDataContext db = new LinqDataContext();
db.InitForQuery();
DataLoadOptions ds = new DataLoadOptions();
ds.LoadWith<Archives>(p => p.Items);
db.LoadOptions = ds;
string Op = null;
var Arc = from p in db.Archives where p.A_Belong == PublicDBClass.SearchVLIdByName(result) select p;
foreach (var a in Arc)
{
Op += " <option>" + a.A_Name + " </option>";
}
string BB = Op;
return BB;
}
二,上传文件基本操作
上传文件
#region 上传的基本操作
int Count = Request.Files.Count;//获取上传文件的数量
int TabCount = (from p in db.UpFile where p.F_BelongI.Contains( Item_ID) select p).Count()+1;
string path = Server.MapPath("..//Upload");
if (!System.IO.Directory.Exists(path))
{
System.IO.Directory.CreateDirectory(path);//没有目录就创建它
}
path = AppDomain.CurrentDomain.BaseDirectory + "Upload/";
for (int i = 0; i < Count; i++)
{
if (Request.Files[i].FileName != "")
{
HttpPostedFileBase hf = Request.Files[i];//取得符合当前条件的input
string filename = System.IO.Path.GetFileName(hf.FileName);//文件名称
hf.SaveAs(Path.Combine(path, filename));//保存文件到服务器目录
UpFile file = new UpFile()
{
F_FilePath = Path.Combine("../Upload/", filename),//F_FilePath = Path.Combine(path, filename)
F_Name = filename,
F_Creativetime = DateTime.Now,
F_ID = FileId + (TabCount + i).ToString(),
F_Uper = Session["User"].ToString(),
F_BelongI = Item_ID,
F_BelongA= A_ID,
F_BelongVL= VL_ID
};
db.UpFile.InsertOnSubmit(file);
db.SubmitChanges();
}
}
#endregion
此处代码解释一下思路,由于上传文件只存在一个表中,所以表内的编号十分重要,在这里我给档案管理员规定好了同一个分类下的文件编号的英文部分要保持一致,同一分类下上传档案的时候只输入英文部分编号,然后通过数字部分进行区分,代码这里通过获取同编号的文件数目,再获取上传文件数量,按顺序进行编号,保证每一个文件的数字编号都保持唯一性。
三,档案查询的一些Tip
查询时采用自定义多条件查询,我采用了通过Json传值后判断有无相应值来进行查询条件的添加,后台代码如下:
public string SearchDB()//返回值是string才可以回传字符串
{
string test = Request["SearchDBFile"];
//JsonConvert.SerializeObject(test2);
Dictionary<string, string> DBDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(test);
string VL_Name = DBDictionary["VL_Name"];
string A_Name = DBDictionary["A_Name"];
string F_ID = DBDictionary["F_ID"];
string F_Name = DBDictionary["F_Name"];
string E_date = DBDictionary["E_date"];
string L_date = DBDictionary["L_date"];
string Item_Name = DBDictionary["Item_Name"];
LinqDataContext db = new LinqDataContext();
db.InitForQuery();
DataLoadOptions ds = new DataLoadOptions();
ds.LoadWith<UpFile>(p => p.Items);
db.LoadOptions = ds;
string BB = null;
string BB2 = null;//权限不足时的返回数据
//上面是查询的总体逻辑,下面是拼接条件查询(重要)
var FIL2 = from p in db.UpFile select p;
if (VL_Name!= "请选择查询卷库"&&VL_Name!="")//全选之后进入查询
{
FIL2 = from p in FIL2 where p.F_BelongVL == PublicDBClass.SearchVLIdByName(VL_Name) orderby p.F_Creativetime select p;
}
if (A_Name!= "请选择..." && !A_Name.Equals("请选择查询案卷"))
{
// FIL2.Where(p => p.F_Belong == SearchAIdByName(A_Name));
FIL2 = from p in FIL2 where p.F_BelongA == PublicDBClass.SearchAIdByName(A_Name) orderby p.F_Creativetime select p;
}
if (Item_Name != "请选择..." && !Item_Name.Equals("请选择分类"))
{
FIL2 = from p in FIL2 where p.F_BelongI == PublicDBClass.SearchFLIDByFLName(Item_Name) orderby p.F_Creativetime select p;
}
if (F_Name!="")
{
FIL2= FIL2.Where(p => p.F_Name.Contains(F_Name)).OrderBy(p=>p.F_Creativetime) ;
}
if (F_ID != "")
{
FIL2 = FIL2.Where(p => p.F_ID.Contains( F_ID)).OrderBy(p => p.F_Creativetime);
}
if(L_date!="")
{
FIL2 = FIL2.Where(p => p.F_Creativetime < Convert.ToDateTime(L_date)).OrderBy(p => p.F_Creativetime);
}
if(E_date != "")
{
FIL2 = FIL2.Where(p=>p.F_Creativetime > Convert.ToDateTime(E_date)).OrderBy(p => p.F_Creativetime);
}
// List<UpFile> files = FIL2.ToList();
foreach (var a in FIL2)
{
string BLAJ = PublicDBClass.SearchANameById(a.F_BelongA);
string BLFL = PublicDBClass.SearchFLNameByFLId(a.F_BelongI);
string BLVL = PublicDBClass.SearchVLIDByAName(BLAJ);
string BLAJ2 = PublicDBClass.SearchVLNameById(BLVL);//找到所属卷库
if (Session["Jur"].ToString() == "none")
{
BB2 += "<tr><td> " + a.F_ID + " </td ><td><a href='../Scan/ScanWord?url2=" + a.F_Name + "' target='_bank'>" + a.F_Name + "</a></td><td>" + a.F_Creativetime + "</td><td>" + a.F_Uper + "</td><td>" + BLFL + "</td><td>" + BLAJ + "</td><td>" + BLAJ2 + "</td><td>" + "<a href='" + a.F_FilePath + "' download = '" + a.F_Name + "'>下载</a></td></tr>";
}
else
{
BB += "<tr><td> " + a.F_ID + " </td ><td><a href='../Scan/ScanWord?url2=" + a.F_Name + "' target='_bank'>" + a.F_Name + "</a></td><td>" + a.F_Creativetime + "</td><td>" + a.F_Uper + "</td><td>" + BLFL + "</td><td>" + BLAJ + "</td><td>" + BLAJ2 + "</td><td>" + "<a href='" + a.F_FilePath + "' download = '" + a.F_Name + "'>下载</a></td><td><button type='button' οnclick='DelFile(\"" + a.F_ID.ToString() + "\")'' >删除</button> </td></tr>";
}
}
if (Session["Jur"].ToString() == "none")
{
BB = BB2;
}
return BB;
}
简单说一下这串代码,思路是自定义查询条件后点击查询,显示在查询页面下方的表格里,表格中的内容通过后台编辑的前台代码存放在Session中在前台显示出来。
中间的一串if判断的都是前面取到的值的情况,前面取值的内容都是在前台通过ajax传递Json获得的。如果有疑问可以在评论区分享给我。
四,前台显示的细节处理
1,必填项
这点没想到VS给了一个非常好的属性,即在需要必填的标签中添加required="required"即可,代码例如下:
<select name="JuanKu" id="JK" class="form-control" onchange="hhh()" required="required">
在这里无论是input还是select等需要输入和操作的都可以添加,form提交后,如果没有进行输入或者选择的内容将会有必填提示,非常方便。
2,网站选项卡上的ico图片显示。
网站选项卡不仅有当前页面的名称,在左边还有一个很漂亮的网站logo,此logo是由ico图标显示的,很简单,只需要在head标签中添加一串代码即可,其中ico图标的制作可以在网上有在线制作。在此附上代码示例:
<link rel="shortcut icon" type="image/x-icon" href="~/Content/img/logoico.ico" />
只需要修改href即可,这段代码一般在母版页的head上。
还有很多内容,持续更新本帖,如果有帮到你,将是我的荣幸。