添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

今天在撈取購物網站資料時發生了一件很詭異的事情,明明在 HtmlNodeCollection 搜尋時在父節點裡明明就是中文字,但在進行 foreach 篩選子節點時卻發生原本的中文decode了  !!!!
經過了三四個小時的google與詢問大大,終於有了結果。

  • 在父節點裡是正常顯示中文 01
  • 到了子節點卻發生decode的現象 02
  • 將字串貼入記事本用IE開啟即正常顯示中文
    館長推薦

    解法如下:

  • 使用 HttpUtility.HtmlDecode 這個方法來恢復正常文字
    HttpUtility.HtmlDecode(nodes_proName[i].InnerText)
    WebClient url = new WebClient(); //將網頁來源資料暫存到記憶體內 MemoryStream ms = new MemoryStream(url.DownloadData("http://www.coolpc.com.tw/evaluate.php")); //使用預設編碼讀入 HTML HtmlDocument doc = new HtmlDocument(); doc.Load(ms, Encoding.Default);
  • 原價屋除了商品的類型以外,類型內的選單(select)有做群組分類,為了要將分類與商品所以先建一個Model
    class Product
    	public string type { get; set; }
    	public string name { get; set; }
    
  • 判斷所要的商品類型(以CPU為例),再擷取該商品類型內選單的分類
    var list_type = new List<string>();
    HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//select[@name='n4']//optgroup");
    foreach (HtmlNode node in nodes)
    	var type = node.Attributes["label"].Value;
    	list_type.Add(type);
    
  • 接下來就要該使擷取商品名稱與價格了
    List<string> list_name = doc.DocumentNode.SelectSingleNode("//select[@name='n4']").InnerText.Split('\n').ToList();
    //刪除不必要的非商品選項
    list_name.RemoveRange(0,3);
    list_name.RemoveAt(list_name.Count - 1);
  • 將商品類型與名稱填入Model
    var models = new List<Product>();
    int number = 0;
    for (int i = 0; i < list_name.Count; i++)
    	string type = list_type[number];
    	string name = list_name[i];
    	if (name == "")
    		number++;
    		models.Add(new Product()
    			type = type,
    			name = name
    		Console.WriteLine("類型:{0} ,", type);
    		Console.WriteLine("名稱:{0}", name);
    Console.ReadLine();

    範例程式:https://github.com/shuangrain/ConsoleApplication_HtmlAgilityPack

    參考:[ASP.NET][C#]使用HtmlAgilityPack(1) 擷取網頁上的股票

    先前提到過 [C#][ASP.NET MVC5] 使用 HttpPostedFileBase 檔案上傳 ,這次我要使用Ajax的方式上傳檔案,但研究了Ajax.BeginForm許久都無法上傳檔案,最後找到使用jQuery Form Plugin來實作此功能。

  • ASP.NET MVC – 使用 jQuery Form Plugin 做檔案上傳
  • ASP.NET MVC – 使用 jQuery Form Plugin 做檔案上傳之加點東西
  • 使用NuGet安裝所需套件

  • 安裝jQuery Form Plugin
  • 安裝Javascript Alert:toastr
    ViewBag.Title = "Upload"; <h2>Upload</h2> @using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) <div class="form-horizontal"> <div class="form-group"> <label class="control-label col-sm-2">選擇檔案</label> <div class="col-sm-10"> <input type="file" name="file"> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" value="提交" class="btn btn-primary" /> @section css @Styles.Render("~/Content/toastr") @section scripts @Scripts.Render("~/bundles/jqueryajax") @Scripts.Render("~/bundles/jqueryform") @Scripts.Render("~/bundles/toastr") <script> $("form").ajaxForm({ iframe: true, dataType: "json", success: function (result) { $("form").resetForm(); if (result.success) { toastr.success(result.message, 'Success Message') else { toastr.error(result.message, 'Error Message') error: function (xhr, textStatus, errorThrown) { $("form").resetForm(); toastr.error('檔案上傳錯誤.', 'Error Message') </script>

    HTML的部分可以不用更動,無須使用Ajax.BeginForm,只需要在JavaScript的地方使用ajaxForm即可將表單轉換成Ajax模式。

    Controller

    [HttpPost]
    public JsonResult Upload(HttpPostedFileBase file)
    	if (file != null && file.ContentLength > 0)
    		var fileName = Path.GetFileName(file.FileName);
    		var path = Server.MapPath("~/App_Data/FileUploads");
    		//若該資料夾不存在,則新增一個
    		if (!Directory.Exists(path))
    			Directory.CreateDirectory(path);
    		path = Path.Combine(path, fileName);
    		file.SaveAs(path);
    		return Json(new
    			success = true,
    			message = fileName,
    			ContentLenght = file.ContentLength
    		}, "text/html");
    	else {
    		return Json(new
    			success = false,
    			message = "請上傳正確的檔案."
    		}, "text/html");
    

    由於前端使用Ajax所以後台回傳資訊則必須從ActionResult修改成JsonResult,這樣才能強制回傳Json格式,需要注意的一點是在IE底下若無指定contentType的話則會出現問題如下圖,必須指定回傳的contentTypetext/html才能在IE底下正常接收資訊。

    最近手賤把Disqus解除帳號連結,卻發現怎麼樣都無法連結帳號,一直顯示Unable to connect to the Disqus API servers如下:

    拜了Google大神很久都找不到原因,無論重新安裝Windows Server還是使用國外HostGator Web Hosting(Windows)都發生同樣錯誤,忽然想起之前安裝這個外掛的時候也有發生這個問題,後來改用Linux後就正常了,於是乎懷疑是否是作業系統的問題,立即開了虛擬機安裝一台Linux測試,在Linux底下沒有做什麼特別的設定,按下登入馬上就連結成功到Disqus。

    個人猜測在Windows裡安裝的php套件少了什麼東西,導致外掛無法正常運作,雖然切回Windows後無法同步留言回Wordpress,但是此外掛還是有正常在運作中可以正常留言,那就先這樣結案吧!

    剛開始在碰ASP.NET MVC的時候,查詢該如何連結資料庫時常常會聽到Entity Framework這個方法,但由於那時沒有太多時間,沒去查太多資料都用SQL自幹,現在閒下來了,就來玩玩看這個東西,首先是環境設定:

  • NuGet安裝MySQL使用Entity Framework時所需要的套件
  • 總共有三個東西要安裝,分別是
  • MySql.Data
  • MySql.Data.Entity
  • MySql.Web
  • 安裝完畢後就要開始設定連結字串,打開Web.config新增連結字串
    <connectionStrings>
    	<add name="MySqlConnectionString" providerName="MySql.Data.MySqlClient" connectionString="Server=server;Database=dbname;UID=username;Password=password" />
    </connectionStrings>
  • 建立MySqlContext.cs並繼承DbContext供後續使用
    public class MySqlContext : DbContext
    	public MySqlContext() : base("MySqlConnectionString") { }
    

    這樣環境就建置完成囉,後續就可以開始使用Entity Framework了!

  • ASP.NET MVC, ENTITY FRAMEWORK CODE FIRST與MYSQL筆記
  • Entity Framework 快速上手與學習資源整理
  • ASP.NET為防止駭客利用大檔案進行DOS(Denial Of Service)攻擊,所以把上傳檔案大小限制在4096KB(4MB),因此當上傳檔案超過4MB時,就會收到System.Web.HttpException 超出最大的要求長度的錯誤訊息如下:

    那如果需要上傳超過4MB的檔案怎麼辦?那就必須修改Web.configsystem.web讓該站自訂大小,修改內容如下:

    <system.web>
    	<httpRuntime targetFramework="4.5" maxRequestLength="102400" executionTimeout="600"/>
    </system.web>
  • maxRequestLength 檔案大小(KB)
  • executionTimeout 上傳時間(秒)
  • 修改完後雖然不會跳出上面的錯誤了,不過卻跳出另外一個訊息:

    拜了Google才發現,原來 Windows Server 2008 (IIS 7.0) 上又多了一個 maxAllowedContentLength 屬性 (單位為 Byte),於是乎又打開了Web.config找到system.webServer,修改內容如下:

    <system.webServer>
    	<security>
    		<requestFiltering>
    			<requestLimits maxAllowedContentLength="1073741824" />
    		</requestFiltering>
    	</security>
    </system.webServer>

    其預設值為 30000000 Bytes (~28.6 MB),所以上傳 30 MB 的檔案就會產生錯誤了。這邊我是修改為1 GB (1024 x 1024 x 1024)可視情況調整。

    綜合以上的修改結果為:

    如果使用者上傳超過設定的最大上限怎麼辦?是不是又會跳出錯誤訊息?不要害怕,只要在Global.asax裡面處理這項錯誤即可,處理方式如下:

    protected void Application_BeginRequest(object sender, EventArgs e)
    	HttpRuntimeSection section = (HttpRuntimeSection)ConfigurationManager.GetSection("system.web/httpRuntime");
    	int maxFileSize = section.MaxRequestLength * 1024;
    	if (Request.ContentLength > maxFileSize)
    			Response.Redirect("~/SizeError.aspx");
    		catch (Exception ex)
    			Logger logger = LogManager.GetCurrentClassLogger();
    			logger.Warn(ex.Message);
    

    一個簡單的上傳功能,想不到有這麼多眉眉角角需要注意,做這行真是不容易QQ

  • ASP.NET如何設定檔案上傳大小可超過預設4096KB(4MB)
  • FileUpload 上傳檔案大小的限制
  • public ActionResult Upload(HttpPostedFileBase file) if (file != null && file.ContentLength > 0) var fileName = Path.GetFileName(file.FileName); var path = Server.MapPath("~/App_Data/FileUploads"); //若該資料夾不存在,則新增一個 if (!Directory.Exists(path)) Directory.CreateDirectory(path); path = Path.Combine(path, fileName); file.SaveAs(path); return RedirectToAction("Upload");
    @using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
        <div class="form-horizontal">
            <div class="form-group">
                <label class="control-label col-sm-2">選擇檔案</label>
                <div class="col-sm-10">
                    <input type="file" name="file">
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <input type="submit" value="提交" class="btn btn-primary" />
    

    這邊要注意的是,如需要使用HttpPostedFileBase上傳檔案的話,則必須添加enctype = "multipart/form-data",不然怎麼樣都沒辦法正常收到資料!
    另外如果使用下列語法是無法接收資料的,因這樣表單並沒有含enctype = "multipart/form-data"這項

    @using (Html.BeginForm("Upload", "Home", new { enctype = "multipart/form-data" }))

    一定要用改為下面的方法

    @using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))

    範例程式:https://github.com/shuangrain/WebApplication_Upload

    在儲存檔案的時候,常常會需要動態新增資料夾,但如果沒有特別處理的話,資料夾無法正常建立,所以需要用到下面的語法來檢查該資料夾是否存在,如不存在則新增。

    using System.IO;
    if (Directory.Exists(資料夾路徑))
        //資料夾存在
        //新增資料夾
        Directory.CreateDirectory(@"C:\temp\");
    

    P.S. 寫入檔案除了要注意資料夾路徑是否存在以外,還要注意該應用程式的權限問題唷!

  •