客戶要求
1. 檔案只能放在 Firewall 內的後台用 Web server (Server A).
2. 使用者只能存取 DMZ 的 Web server (Server B).
3. Server B 只能用 HTTP 通過 Firewall 向 Server A 要資料.(i.e. Server B 不能掛戴 Server A 的目錄成為虛擬目錄)
所以在 Server B 上面建立了一支程式用 HTTP 的方式讀取 Server A 的檔案再寫出去.
例如, http://ServerB/Upload/test.pdf 會讀取 http://ServerA/Upload/test.pdf 再送到 Client 端
namespace WWW.Controllers
{
public class UploadController : Controller
{
// GET: Upload
public void Index(string Filename)
{
//Create a stream for the file
Stream stream = null;
//This controls how many bytes to read at a time and send to the client
int bytesToRead = 10000;
// Buffer to read bytes in chunk size specified above
byte[] buffer = new Byte[bytesToRead];
string url = "http://admin-dev.nanya.bike.idv.tw/newnanyaback/Upload/" + Filename;
// The number of bytes read
try
{
//Create a WebRequest to get the file
HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create(url);
//Create a response for this request
HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();
if (fileReq.ContentLength > 0)
fileResp.ContentLength = fileReq.ContentLength;
//Get the Stream returned from the response
stream = fileResp.GetResponseStream();
// prepare the response to the client. resp is the client Response
var resp = HttpContext.Response;
if (Filename.ToLower().EndsWith(".png") ||
Filename.ToLower().EndsWith(".jpg") ||
Filename.ToLower().EndsWith(".jpeg") ||
Filename.ToLower().EndsWith(".gif")
)
{
resp.ContentType = "image";
}
else
{
//Indicate the type of data being sent
resp.ContentType = "application/octet-stream";
//Name the file
resp.AddHeader("Content-Disposition", "attachment; filename=\"" + HttpUtility.UrlEncode(Filename, Encoding.UTF8) + "\"");
}
resp.AddHeader("Content-Length", fileResp.ContentLength.ToString());
int length;
do
{
// Verify that the client is connected.
if (resp.IsClientConnected)
{
// Read data into the buffer.
length = stream.Read(buffer, 0, bytesToRead);
// and write it out to the response's output stream
resp.OutputStream.Write(buffer, 0, length);
// Flush the data
resp.Flush();
//Clear the buffer
buffer = new Byte[bytesToRead];
}
else
{
// cancel the download if client has disconnected
length = -1;
}
} while (length > 0); //Repeat until no data is read
}
finally
{
if (stream != null)
{
//Close the input stream
stream.Close();
}
}
}
}
}
但不是這樣就好了, 在 RouteConfig.cs 中要加上:
routes.MapRoute(
name: "Upload",
url: "Upload/{filename}",
defaults: new { controller = "Upload", action = "Index", filename = UrlParameter.Optional }
);
此外在 Web.Config 中也要加上:
<system.webServer>
<handlers>
<add name="UrlRoutingHandler_Upload"
type="System.Web.Routing.UrlRoutingHandler,
System.Web, Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
path="/Upload/*"
verb="GET"/>
</handlers>
</system.webServer>
參考:
http://stackoverflow.com/questions/5596747/download-stream-file-from-url-asp-net
http://blog.darkthread.net/post-2014-12-05-mvc-routing-for-url-with-filename.aspx
Bike, 2016/12/1 下午 09:34:30
2016 / 10 / 30 搬機房, 有幾件事沒有做好, 記錄一下:
1. Firewall 沒設定好, 下次要一中兩個人一起設定.
2. 有一個客戶的 DNS 等了一整天才生效, 要檢查所有網站的 TTL 和 Refresh 時間, 最好都在一個小時以內.
3. Email 主機: 有些客戶原來是用 msa.hinet.net 這個 SMTP, 搬到非 Hinet 的機房後就不能寄信了.
4. 某一個客戶的 DNS 沒改好, 因為在自已的 DNS Server 上面看到有記錄, 就誤判是我們代管的, 應該要用 Hinet 或 Google 來確認 NS Record 為何. 已刪除它的 DNS 記錄.
5. 202 的 .8 網路線沒插好, 主機開起來後, 要確認可以從每一個介面 Ping 出去.
6. 新 Firewall , 內部 IP 無法連到 Virtual Server: --> 要由內部 IP 連線到 Virtual Server 測試. 最好是在 hosts 上面都有 127.0.0.1 的設定.
7. 最好不要在下半年換機房, 比較忙, 客戶的活動也比較多.
8. Windows 的 DNS 若是直接修改 DNS 檔案. 因為 SOA 的序號沒有修改, 所以 Client 伺服器要手動重新讀取資料.
9. 要記得改 TWNIC 的 DNS Server設定.
Bike, 2016/11/3 上午 11:05:19
找了兩三篇文章再加一點修正才組出來的, 記錄一下, 要用 iTextSharp 哦.
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
---
string oldFile = Server.MapPath("/Content/PDF/300000419_20160929162658862.pdf"); //"oldFile.pdf";
string newFile = oldFile.Replace(".pdf", "_New11.pdf");
// open the reader
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
int NumberOfPages = reader.NumberOfPages;
// open the writer
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
// the pdf content
PdfContentByte cb = writer.DirectContent;
string text = "Watermark...";
string windir = Environment.GetEnvironmentVariable("windir");
Chunk textAsChunk = new Chunk(text, new Font(BaseFont.CreateFont(windir + "\\Fonts\\mingliu.ttc,0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED), 20, Font.NORMAL, new BaseColor(255,0,0)));
// create the new page and add it to the pdf
for (int i = 1; i<= NumberOfPages; i++)
{
if(i > 1)
{
document.NewPage();
}
ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, new Phrase(textAsChunk), 0, 0, 0);
PdfImportedPage page = writer.GetImportedPage(reader, i);
cb.AddTemplate(page, 0, 0);
}
// close the streams and voilá the file should be changed :)
document.Close();
fs.Close();
writer.Close();
reader.Close();
Response.Write(newFile + "<br>");
Response.Write(NumberOfPages + "<br>");
Bike, 2016/9/29 下午 06:23:59
--抓所有的 Table
Select * from INFORMATION_SCHEMA.TABLES
--抓所有的 COLUMNS
Select * from INFORMATION_SCHEMA.COLUMNS
--抓欄位的 Description
select
st.name [Table],
sc.name [Column],
sep.value [Description]
from sys.tables st
inner join sys.columns sc on st.object_id = sc.object_id
left join sys.extended_properties sep on st.object_id = sep.major_id
and sc.column_id = sep.minor_id
and sep.name = 'MS_Description'
where st.name = 'TableName'
and sc.name = 'ColumnName'
--修改欄位的 Description.
EXEC sp_updateextendedproperty
@name = N'MS_Description', @value = 'Your description',
@level0type = N'Schema', @level0name = 'dbo',
@level1type = N'Table', @level1name = 'TableName',
@level2type = N'Column', @level2name = 'Name';
EXEC sp_addextendedproperty
@name = N'MS_Description', @value = 'Code description',
@level0type = N'Schema', @level0name = 'dbo',
@level1type = N'Table', @level1name = 'TableName',
@level2type = N'Column', @level2name = 'ColumnName';
--新增 Table 的 extendedproperty
EXEC sp_addextendedproperty
@name = N'Description', @value = 'Hey, here is TableName description!',
@level0type = N'Schema', @level0name = 'dbo',
@level1type = N'Table', @level1name = 'TableName'
GO
--修改 Table 的 extendedproperty
EXEC sp_updateextendedproperty
@name = N'Description', @value = 'Hey, here is my description! 123',
@level0type = N'Schema', @level0name = 'dbo',
@level1type = N'Table', @level1name = 'TableName'
GO
--讀取 Extended Property
SELECT sys.objects.name AS TableName, ep.name AS PropertyName,
ep.value AS Description
FROM sys.objects
CROSS APPLY fn_listextendedproperty(default,
'SCHEMA', schema_name(schema_id),
'TABLE', name, null, null) ep
WHERE sys.objects.name NOT IN ('sysdiagrams')
ORDER BY sys.objects.name
--讀取 Column 的 Description
SELECT objtype, objname, name, value
FROM fn_listextendedproperty (NULL, 'schema', 'dbo', 'table', 'TableName', 'column', default);
GO
--讀取特定 Table 的 Description
SELECT *
FROM fn_listextendedproperty (NULL, 'schema', 'dbo', 'table', 'TableName', default, default);
GO
--讀取 所有 Table 的 Description
SELECT *
FROM fn_listextendedproperty (NULL, 'schema', 'dbo', 'table', default, default, default);
GO
--新增或修改資料表說明
IF not exists(SELECT * FROM ::fn_listextendedproperty (NULL, 'user', 'dbo', 'table', '資料表名稱', NULL, NULL))
BEGIN
exec sp_addextendedproperty 'MS_Description', '資料表說明', 'user', 'dbo', 'table', '資料表名稱'
END
ELSE
BEGIN
exec sp_updateextendedproperty 'MS_Description', '資料表說明', 'user', 'dbo', 'table', '資料表名稱'
END
--新增或修改欄位說明
IF not exists(SELECT * FROM ::fn_listextendedproperty (NULL, 'user', 'dbo', 'table', '資料表名稱', 'column', '欄位名稱'))
BEGIN
exec sp_addextendedproperty 'MS_Description', '欄位說明', 'user', 'dbo', 'table', '資料表名稱', 'column', '欄位名稱'
END
ELSE
BEGIN
exec sp_updateextendedproperty 'MS_Description', '欄位說明', 'user', 'dbo', 'table', '資料表名稱', 'column', '欄位名稱'
END
Bike, 2016/6/29 下午 04:42:25