public class UploadController : ApiController
{
public async Task<object> PostFormData()
{
var provider = new MultipartMemoryStreamProvider();
if (! Request.Content.IsMimeMultipartContent())
{
return "no file";
}
//要注意這裡的 await
await Request.Content.ReadAsMultipartAsync(provider);
foreach (var content in provider.Contents)
{
if (content.Headers.ContentDisposition.FileName != null)
{
string localFilename = content.Headers.ContentDisposition.FileName.Replace("\"", "");
System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(@"~/App_Data/Temp/"));
string filename = HttpContext.Current.Server.MapPath(@"~/App_Data/Temp/" + localFilename);
if (System.IO.File.Exists(filename))
{
System.IO.File.Delete(filename);
}
using (var fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
var contentStream = await content.ReadAsStreamAsync();
await contentStream.CopyToAsync(fileStream);
Trace.WriteLine("Save To" + filename);
}
}
}
return "OK";
}
}
/// <summary>
/// 檔案檢查
/// </summary>
/// <param name="actionContext"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
Trace.WriteLine("ApiCheckFile OnActionExecutingAsync");
var request = actionContext.Request;
if (!request.Content.IsMimeMultipartContent())
{
return;
}
var provider = new MultipartMemoryStreamProvider();
await request.Content.ReadAsMultipartAsync(provider);
//把 provider 存入 System.Web.HttpContext.Current.Items 之中,以便在 controller 中再度使用
System.Web.HttpContext.Current.Items["MimeMultipartContentProvider"] = provider;
foreach (var content in provider.Contents)
{
if (content.Headers.ContentDisposition.FileName != null)
{
var filename = content.Headers.ContentDisposition.FileName.Replace("\"", "");
Trace.WriteLine(filename);
var ext = System.IO.Path.GetExtension(filename);
if (!".jpg,.jpeg,.png".Contains(ext.ToLower()))
{
throw new Exception("file format error.");
}
}
}
return;
}
public async Task<object> PostFormData()
{
//改由 HttpContext.Current.Items 中,讀取資料。
MultipartMemoryStreamProvider provider = (MultipartMemoryStreamProvider)System.Web.HttpContext.Current.Items["MimeMultipartContentProvider"];
//如果沒有經過 filter,provider會是 null, 這時就要直接由 Request.Content 讀入 provider
if (provider == null)
{
provider = new MultipartMemoryStreamProvider();
Request.Content.ReadAsMultipartAsync(provider);
}
foreach (var content in provider.Contents)
{
if (content.Headers.ContentDisposition.FileName != null)
{
string localFilename = content.Headers.ContentDisposition.FileName.Replace("\"", "");
Trace.WriteLine("FileName: " + localFilename);
Trace.WriteLine("FileName: " + @"~/App_Data/Temp/" + localFilename);
System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(@"~/App_Data/Temp/"));
string filename = HttpContext.Current.Server.MapPath(@"~/App_Data/Temp/" + localFilename);
if (System.IO.File.Exists(filename))
{
System.IO.File.Delete(filename);
}
using (var fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
var contentStream = await content.ReadAsStreamAsync();
await contentStream.CopyToAsync(fileStream);
Trace.WriteLine("Save To" + filename);
}
}
else
{
var contentStream = await content.ReadAsStreamAsync();
var reader = new System.IO.StreamReader(contentStream);
var data = reader.ReadToEnd();
Trace.WriteLine("data: " + data);
}
}
return "OK";
}
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
Debug.WriteLine("MvcCheckFileFilter OnActionExecuting");
if (actionContext.HttpContext.Request.Files.Count > 0)
{
for (int i = 0; i < actionContext.HttpContext.Request.Files.Count; i++)
{
System.Web.HttpPostedFileBase file = actionContext.HttpContext.Request.Files[i];
if (System.IO.Path.GetExtension(file.FileName) != ".jpg")
{
throw new Exception("file format error.");
}
Debug.WriteLine(i + "MvcCheckFileFilter OnActionExecuting File type: " + file.FileName.ToString());
}
}
//以下寫法會發生錯誤: 無法將類型 'System.String' 的物件轉換為類型 'System.Web.HttpPostedFileBase'。
//foreach (HttpPostedFileBase file in actionContext.HttpContext.Request.Files)
//{
// if (System.IO.Path.GetExtension(file.FileName) != ".jpg")
// {
// throw new Exception("file format error.");
// }
//}
}
對於PC版大尺吋的螢幕,當網站要 feed 資料到 facebook 時,可以使用 javascript SDK 的
FB.ui => method:'feed' 方式處理,參考位置。此方法會popup小視窗讓user可以分享資料出去。
但是遇到手機版網頁就有點麻煩,實測上手機版的 chrome 會出現轉不停的情況,無法分享;而iPhone則是另開新頁面處理,可以成功但是會多一個分頁。所以手機版網頁建議使用 redirect 方式處理分享機制,參考位置
var fbUrl = "https://www.facebook.com/dialog/feed?" +
"app_id=122465741241119&display=touch" +
"&link=" + encodeURIComponent("http://www.shopunt.com/tch/FixPage.aspx?id=525") +
"&picture=" + encodeURIComponent("http://www.shopunt.com/tch/event/2014-nail-enrollment/fb_200x200.jpg") +
"&description=" + encodeURIComponent("市價不斐的光療DIY教學,UNT傾囊相授!10場巡迴免費教學,讓妳輕鬆掌握光療DIY訣竅,並搶先體驗秋冬最新流行色!現場打卡,再送時尚美甲工具組") +
"&redirect_uri=" + encodeURIComponent("http://www.shopunt.com/tch/event/2014-nail-enrollment/Handler.ashx?fun=FBCallback");
當然以 redirect 處理與 javascript 方式處理是兩種不同的方式,redirect 方式的 callback 網址 (redirect_uri)要接收facebook 導回的 post_id , javascript 方式則是 callback function 處理 post_id