2013-07-22 53 views
0

我有一個C#方法,如果你從另一個C#方法調用它,但不是從JavaScript調用。我如何使我的ajax調用工作?如何從System.Web.HttpContext.Current.Response.BinaryWrite(byteArray)中下載文件;從JavaScript而不是C#

我需要基於傳入的ID來獲取文件,所以我有一個帶有statusID的ajax文章。該ID正在我的C#方法中拉取正確的文件,它只是不提供文件保存對話框。但是,如果我從我的C#頁面加載方法調用此方法並使用靜態statusID進行測試,它就可以正常工作。

這裏是C#方法:

public void Get_Attachment_By_StatusID(int statusID) 
    { 
     SqlDataReader _reader = null; 
     string _connString = "Data Source=133.31.32.33;Initial Catalog=Reports;Integrated Security=True"; 

     string sql = "SELECT a.StatusID ,a.DocumentName ,a.MIMETypeID ,a.Binary ,a.CreatedDate ,a.CreatedBy " + 
      ",b.MIMEType FROM Attachments a Inner join MIME_Types b on a.MIMETypeID = b.ID " + 
      "WHERE [StatusID] = {0} "; 

     sql = string.Format(sql, statusID); 

     try 
     { 
      _connection = new SqlConnection(_connString); 
      _connection.Open(); 

      using (SqlCommand cmd = new SqlCommand(sql, _connection)) 
      { 
       cmd.CommandType = System.Data.CommandType.Text; 
       _reader = cmd.ExecuteReader(); 

       if (_reader.HasRows) 
       { 
        while (_reader.Read()) 
        { 
         System.Web.HttpContext.Current.Response.ClearContent(); 
         System.Web.HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; 
         System.Web.HttpContext.Current.Response.ContentType = _reader["MIMEType"].ToString(); 
         System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + _reader["DocumentName"].ToString() + ";"); 
         byte[] b = (byte[])_reader["Binary"]; 
         System.Web.HttpContext.Current.Response.BinaryWrite(b); 
         System.Web.HttpContext.Current.Response.Flush(); 
         System.Web.HttpContext.Current.Response.Close(); 
        } 

       } 

       _reader.Close(); 
       _connection.Close(); 
      } 
     } 
     catch (Exception ex) 
     { 
      //Log exception to error Logging app 
      string err = ex.ToString(); 

     } 
     finally 
     { 
      if (_connection != null) 
       _connection.Close(); 
      if (_reader != null) 
       _reader.Close(); 
     } 
    } 

這裏是如何我從我的頁面調用它,在javascript:

function GetFile(statusID) { 
    var url = '/Home/Get_Attachment_By_StatusID'; 

    $.ajax({ 
     url: url, 
     type: 'post', 
     cache: false, 
     data: JSON.stringify({ "statusID": statusID }), 
     contentType: 'application/json', 
     success: function (data) { 

     } 
    }); 
} 

什麼也沒有發生。在Chrome瀏覽器中,我沒有在JavaScript控制檯中看到任何內容,而在IE中,我的控制檯吐露了這些:「XML5619:錯誤的文檔語法。」

再一次,如果我進入控制器,並調用我的頁面加載方法的方法,它會顯示保存文件對話框,並保存文件就好了。所以我一定是做錯了我的javascript/jquery/ajax ...

我是新來的MVC4,知道我在這裏失去了一些東西。我錯過了什麼?

+1

爲什麼要發送J SON到URL?它是否與「正常」POST查詢字符串?嘗試使用'data:{statusID:statusID}'(並丟失'contentType')。 –

+0

我會改變你的行動來接受GET請求,而不是'POST',並簡單地改變你的客戶端上的代碼來做'window.location = path/to/action_to_download_file /;' – Icarus

+0

@Rocket Hazmat,statusID得到那裏很好,字節數組填充了正確的文件。 – codesforcoffee

回答

1

這裏有一個建議,主要是基於回答LastCoder:

裝飾與[HttpGet]屬性你的行動和改變參數名稱id

[HttpGet] 
public void Get_Attachment_By_StatusID(int id) ... 

現在,在您的客戶端代碼,只需執行以下操作:

function GetFile(statusID) { 
    var url = '/Home/Get_Attachment_By_StatusID/'+statusID; 
    window.location=url; 
} 
+0

- 感謝您試圖回答我的問題給LastCoder,但我做了你所說的並且仍然在我的Get_Attachment_By_StatusID方法中得到一個id參數爲null。 – codesforcoffee

+0

你用'[HttpGet]'屬性裝飾過它嗎?並將參數名稱更改爲'id'?如果是這樣,請發佈您的更新代碼。 – Icarus

+0

我做了,但它沒有工作,直到我進入我的路由選項,並添加ID作爲我的MVC項目的可選參數。 在RouteConfig - > RegisterRoutes,我現在有這個,它的工作原理! routes.MapRoute( name:「Default」, url:「{controller}/{action}/{id}」, 默認值:new {controller =「Home」,action =「Home」,id = UrlParameter。可選的 } – codesforcoffee

2

使用window.open('CONTROLLER_URL/STATUS_ID');而不是AJAX請求。

<a target="_blank" href="javascript:window.open('/Home/Get_Attachment_By_StatusID/12345');">Test</a> 
+0

謝謝,我會去試試這個! – codesforcoffee

+0

+1,但我會刪除'href =「javascript:...」'並將它放在外面以保持Javascript代碼與標記分開。 – Icarus

+0

@LastCoder你可以給我一個在我的c#方法中改變什麼的樣本,使這個工作?現在它抱怨statusID爲空。如何使用/ Home/Get_Attachment_By_StatusID /?後的URL添加到URL中? – codesforcoffee

相關問題