var combineBody = Expression.AndAlso(e1.Body, Expression.Invoke(e2, e1.Parameters[0]));
var finalExpression = Expression.Lambda<Func<TestClass, bool>>(combineBody, e1.Parameters).Compile();
public static class ExpressionExtension
{
public static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> e1, Expression<Func<T, bool>> e2)
{
var combineE = Expression.AndAlso(e1.Body, Expression.Invoke(e2, e1.Parameters[0]));
return Expression.Lambda<Func<T, bool>>(combineE, e1.Parameters);
}
public static Expression<Func<T, bool>> OrElse<T>(this Expression<Func<T, bool>> e1, Expression<Func<T, bool>> e2)
{
var combineE = Expression.OrElse(e1.Body, Expression.Invoke(e2, e1.Parameters[0]));
return Expression.Lambda<Func<T, bool>>(combineE, e1.Parameters);
}
}
Expression<Func<Market, bool>> e1 = e => e.Is_Deleted == isDelete;
Expression<Func<Market, bool>> e2 = e => string.IsNullOrEmpty(marketNo) || e.MarketNo.ToUpper().Contains(marketNo.ToUpper());
return new
{
andMarkets = Ds.PageContext.ShopBandContext.Markets.Where(e1.AndAlso(e2)).ToList(),
orMarkets = Ds.PageContext.ShopBandContext.Markets.Where(e1.OrElse(e2)).ToList(),
};
public static Expression<Func<T, bool>> OrElseAll<T>(this IEnumerable<Expression<Func<T, bool>>> exps)
{
if (exps.Count() == 1)
{
return exps.First();
}
var e0 = exps.First();
var orExp = exps.Skip(1).Aggregate(e0.Body, (x, y) => Expression.OrElse(x, Expression.Invoke(y, e0.Parameters[0])));
return Expression.Lambda<Func<T, bool>>(orExp, e0.Parameters);
}
public static Expression<Func<T, bool>> AndAlsoAll<T>(this IEnumerable<Expression<Func<T, bool>>> exps)
{
if (exps.Count() == 1)
{
return exps.First();
}
var e0 = exps.First();
var orExp = exps.Skip(1).Aggregate(e0.Body, (x, y) => Expression.AndAlso(x, Expression.Invoke(y, e0.Parameters[0])));
return Expression.Lambda<Func<T, bool>>(orExp, e0.Parameters);
}
Expression<Func<Market, bool>> q = e =>
e.Is_Deleted == "N"
&& (string.IsNullOrEmpty(marketNo) || e.MarketNo.ToLower().Contains(marketNo.ToLower()))
&& (string.IsNullOrEmpty(isCombination) || isCombination != "Y" || e.TypeEnum == 200);
if (!string.IsNullOrEmpty(name))
{
var nameList = name.Split(',').Select(e => e.Trim())
.Where(e => !string.IsNullOrEmpty(e));
if (nameList.Any())
{
q = q.AndAlso(nameList
.Select(s => (Expression<Func<Market, bool>>)(e => e.Name.ToLower().Contains(s.ToLower())))
.OrElseAll());
}
}
internal class MergeTool : ExpressionVisitor
{
private readonly ParameterExpression _parameter;
protected override Expression VisitParameter(ParameterExpression node)
{
return base.VisitParameter(_parameter);
}
internal MergeTool(ParameterExpression parameter)
{
_parameter = parameter;
}
public static Expression<Func<T, bool>> MergedExpression<T>(Expression<Func<T, bool>> e1, Expression<Func<T, bool>> e2)
{
ParameterExpression param = Expression.Parameter(typeof(T));
BinaryExpression MergeBody = Expression.AndAlso(e1.Body, e2.Body);
var ReplacedBody = (BinaryExpression)new MergeTool(param).Visit(MergeBody);
return Expression.Lambda<Func<T, bool>>(ReplacedBody, param);
}
}
使用時要 Compile
var mergedExpression = MergeTool.MergedExpression(e1, e2);
var list = testList.Where(mergedExpression.Compile());
<configuration>
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<add segment=".svn" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
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.");
// }
//}
}