asp.net mvc webapi 2 提供了 IHttpActionResult 這個界面

這個界面的效果基本上是跟HttpResponseMessage是一樣的 但是在回傳值的表示有些微的不一樣,以下是整理表

IHttpActionResult HttpResponseMessage Request.CreateResponse(HttpStatusCode)
Ok() HttpStatusCode.OK
InternalServerError() HttpStatusCode.InternalServerError
NotFound() HttpStatusCode.NotFound

more on http://msdn.microsoft.com/zh-tw/library/system.web.http.apicontroller_methods(v=vs.118).aspx

這樣子寫起來就乾淨很多了

javascript基本操作html5的 local storage方法 image_thumb.png

1
2
3
4
5
// set item val
window.localstorage.setItem(key,value);
window.localstorage.getItem(key);
window.localstorage.removeItem(key);
window.localstorage.clear();

如果要把array object存入到localstorage裡面,需要把object轉換成文字.所以可透過json的方法來處理

1
2
JSON.stringify(object);
JSON.parse(value);

ref:

http://www.w3schools.com/html/html5_webstorage.asp

http://blog.roodo.com/rocksaying/archives/15967715.html

處理狀況

當要同一時間新增大量資料時,如果單純用EF的新增方式,速度會讓人吐血。 所以需要透過BulkInsert的方式處理,但是又不想自己另外寫ado的方式處理,所以就要透過extenstion的方式, 讓EF的功能加強一下

##安裝 EntityFramework.BulkInsert-ef6

Nuget

##參考文件

http://efbulkinsert.codeplex.com/

##(用法)Demo Code

1
2
3
4
5
6
7
8
using(context db = new context()){
// 原本會用
// db.tables.AddRange(entities);
// 改用
db.BulkInsert(entities);

db.SaveChanges();
}

##執行結果 非常快速

Ref: http://www.dotnet-tricks.com/Tutorial/entityframework/2VOa140214-Entity-Framework-6-Code-First-Migrations-with-Multiple-Data-Contexts.html

如何動態產生Database

如果利用Code first的方式,搭配DbMigration即可完成工作

  • DBContext.cs
1
2
3
4
5
6
7
8
9
10
11
public class DemoContext : DbContext
{
public DemoContext() { }
public DemoContext(string ConnectionString)
: base(ConnectionString)
{
Database.SetInitializer(new CustomInitializer());
Database.Initialize(true);
}
public DbSet<Blog> Blogs { get; set; }
}
  • CustomInitializer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
using System.Linq;

internal sealed class Configuration : DbMigrationsConfiguration<DemoContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
MigrationsDirectory = @"Migration";
}


protected override void Seed(DemoContext context)
{
}
}

class CustomInitializer : IDatabaseInitializer<DemoContext>
{
public void InitializeDatabase(DemoContext context)
{
if (!context.Database.Exists() || !context.Database.CompatibleWithModel(false))
{
var configuration = new Configuration();
configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString, "System.Data.SqlClient");
var migrator = new DbMigrator(configuration);
migrator.Update();
}
}
}
  • client端
1
2
using (var db = new AtaBookContext(connection1)){}
using (var db = new AtaBookContext(connection2)){}

connection1和connection2分別指到不同的資料庫,EF就會根據連線字串的設定產生相對應的資料庫

當要在htmlHelper裡面使用angularjs的屬性時, 原本的ng-model變成ng_model, 將 - 變成 _ 即可

例如:

1
2
3
4
5
6
@Html.DropDownList("dropdown", (IEnumerable<SelectListItem>)ViewBag.items, new { ng_model = "currentSelect", ng_change = "selectChanges()" })

會產生
<select id="dropdown" name="dropdown" ng-change="selectChanges()" ng-model="currentSelect">
<options>something</options>*n
</select>

#NOTE: Youtube link: http://youtu.be/S8XL1L_1Lyw

  • Abstract Factory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Patterns
{
class Program
{
public static Object Create(string className, Dictionary<String, Object> values)
{
Type type = Type.GetType(className);
Object instance = Activator.CreateInstance(type);
foreach (var entry in values)
{
type.GetProperty(entry.Key).SetValue(instance, entry.Value, null);
}
return instance;
}
static void Main(string[] args)
{
Console.WriteLine(Create("Patterns.Book", new Dictionary<string, object>()
{
{"Title", "Some titles"},
{"Pages", 100}
}));

Console.WriteLine(Create("Patterns.CD", new Dictionary<string, object>()
{
{"Title", "Some CD"},
{"Volume", 12}
}));
}
}

class Book
{
public string Title { get; set; }
public int Pages { get; set; }
public override string ToString()
{
return string.Format("Book {0} {1}", Title, Pages);
}
}

class CD
{
public string Title { get; set; }
public int Volume { get; set; }
public override string ToString()
{
return string.Format("CD {0} {1}", Title, Volume);
}
}
}

  • Cascade Pattern
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Patterns
{
class Program
{

static void Main(string[] args)
{
// Sect I
//Mailer mailer = new Mailer();
//mailer.from("[email protected]");
//mailer.to("[email protected]");
//mailer.subject("subjeccccttt");
//mailer.message("contents blah blah");
//mailer.send();

// Sect II- Cascade way
new Mailer().from("[email protected]")
.to("[email protected]")
.subject("subjeccccttt")
.message("contents blah blah")
.send();
}
}
// Sect I
//class Mailer
//{
// public void to(string toAdrr) { }
// public void from(string fromAddr) { }
// public void subject(string sub){}
// public void message(string msg) { }
// public void send() { }
//}

// Sect II
class Mailer
{
public Mailer to(string toAdrr) { return this; }
public Mailer from(string fromAddr) { return this; }
public Mailer subject(string sub) { return this; }
public Mailer message(string msg) { return this; }
public void send() { }
}
}

  • Pluggable Behavior
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Patterns
{
class Program
{
static int totalValues(int[] values)
{
int total = 0;
foreach (var value in values)
{
total += value;
}
return total;
}
static int totalEvenValues(int[] values)
{
int total = 0;
foreach (var value in values)
{
if (value % 2 == 0) total += value;
}
return total;
}
static int totalOddValues(int[] values)
{
int total = 0;
foreach (var value in values)
{
if (value % 2 != 0) total += value;
}
return total;
}
static int totalSelectValues(int[] values, Func<int, bool> selector)
{
int total = 0;
foreach (var value in values)
{
// pass value(first param) into function and return second param value
if (selector(value)) total += value;
}
return total;
}
//
static void Main(string[] args)
{
int[] values = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Console.WriteLine(totalValues(values));
Console.WriteLine(totalEvenValues(values));
Console.WriteLine(totalOddValues(values));

Console.WriteLine("==================");
// re-write
// define functioin in lambda format
// ref: http://msdn.microsoft.com/zh-tw/library/bb397687(v=vs.110).aspx
Console.WriteLine(totalSelectValues(values, (value) => true));
Console.WriteLine(totalSelectValues(values, (value) => value % 2 == 0));
Console.WriteLine(totalSelectValues(values, (value) => value % 2 != 0));
}
}
}

  • Execute Around Method Pattern

part1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Patterns
{
class Program
{
class Resource
{
public Resource()
{
Console.WriteLine("Creating...");
}
public void op1()
{
Console.WriteLine("op1...");
}
public void op2()
{
Console.WriteLine("op2...");
}
~Resource()
{
Console.WriteLine("cleanup exensive resource");
}

}
public static void Main(string[] args)
{
{
Resource resource = new Resource();
resource.op1();
resource.op2();
}
Console.WriteLine("out of the block");
}
}
}

執行結果: 執行結果

part2 (with using())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Patterns
{
class Program
{
class Resource : IDisposable
{
public Resource()
{
Console.WriteLine("Creating...");
}
public void op1()
{
Console.WriteLine("op1...");
}
public void op2()
{
Console.WriteLine("op2...");
}
~Resource()
{
Clearnup();
}
public void Dispose()
{
Clearnup();
GC.SuppressFinalize(this);
}
private void Clearnup()
{
Console.WriteLine("cleanup exensive resource");
}
}
public static void Main(string[] args)
{
// this require class that implement IDisposable
using (Resource resource = new Resource())
{
resource.op1();
resource.op2();
}
Console.WriteLine("out of the block");
}
}
}

執行結果

part3 with Execute Around Method Pattern

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Patterns
{
class Program
{
class Resource
{
//Call Resource class from here
public static void Use(Action<Resource> block)
{
Resource resouce = new Resource();
try
{
block(resouce);
}
finally
{
resouce.Clearnup();
}

}

//change public to protected
// can't new class in normal way : class _class = new class()
protected Resource()
{
Console.WriteLine("Creating...");
}

public void op1()
{
Console.WriteLine("op1...");
}
public void op2()
{
Console.WriteLine("op2...");
}

private void Clearnup()
{
Console.WriteLine("cleanup exensive resource");
}
}
public static void Main(string[] args)
{
{
Resource.Use(
(resource) =>
{
resource.op1();
resource.op2();
});
}
Console.WriteLine("out of the block");
}
}
}

執行結果

Ref from G+

Ater upgrading to AS 0.5.4 I am getting this error 「Failed to set up SDK Error:Module 『AndroinoTerm』: platform 『android-18』 not found」 while I already have android-18 installed. My sdk path is correctly setup and I am also able to run my project successfully. Does Anybody else having this issue ?

Solution: 1. Change sdk folder location 2. update sdk path in android studio 3. change back to original location 4. update sdk path setting in android studio again 5. problem solved

當網頁要讀取一個很大量的資料時,通常都會透過分頁的方式來顯示資料。 如果透過WebApi+OData的特性來做分頁,作法很單純 設定 WebApiConfig.cs

1
2
//加入
config.EnableQuerySupport();

假設原本的API寫法如下

1
2
3
4
5
[Route("api/Customer")]
public IEnumerable<customers> Getcustomers()
{
return db.customers.AsEnumerable();
}

改成

1
2
3
4
5
[Route("api/Customer")]        
public IQueryable<customers> Getcustomers()
{
return db.customers.AsQueryable();
}

那在client端要呼叫api的url中,在加上OData的查詢語法來取得所要的資料區段,來達成分頁的效果

指令 說明 範例
top 結果挑出最前面的幾筆 ?$top=3
skip 略過幾筆。可用於分頁顯示 ?$skip=10
orderby 排序 ?$orderby=SupplierID,ProductID
filter 篩選
gt : > , 大於 $filter=ProductID gt 10
lt : < , 小於 $filter=ProductID lt 10
ge : >=, 大於等於 $filter=ProductID ge 10
le : <=, 小於等於 $filter=ProductID le 10
eq : =, 等於 $filter=ProductID eq 10
ne : <>, 不等於 $filter=ProductID ne 10

參考資料: http://msdn.microsoft.com/en-us/library/windowsazure/gg312156.aspx

如果要利用OData取得所有的資料筆數時,上述的寫法沒有辦法做到,所以要稍微改寫一下原本的寫法

1
2
3
4
5
6
7
8
9
[Route("api/Customer")]   
public PageResult<customers> Getcustomers(ODataQueryOptions<customers> options)
{
var results = options.ApplyTo(db.customers.AsQueryable());
return new PageResult<customers>(
results as IEnumerable<customers>, // Items
Request.GetNextPageLink(), // NextPageLink
Request.GetInlineCount()); // Count
}

要傳入的東西是一樣的,但是回傳的結果會變成

1
2
3
4
5
{
"Items":[data....],
"NextPageLink": null,
"Count": 12345
}

所以在接收時要再調整

當$filter的查詢欄位是guid時

所送出的值前面要加上 guid 的關鍵字

1
?$filter=field eq guid'<value>'

  1. In your Windows 8 VM, go to Control Panel > System > Advanced system settings > Computer Name and click Change. Name this whatever you like, e.g. 「windows」. Restart your VM.

  2. Open CMD or Powershell as administrator. Add a URL ACL entry for your new name on the port of your choice, e.g. netsh http add urlacl url=http://windows:8080/ user=everyone

  3. Open CMD or Powershell as administrator. Add an inbound firewall rule for this new port. In Windows 8, the syntax is: netsh advfirewall firewall add rule name=「IISExpressWeb」 dir=in action=allow protocol=TCP localport=8080

In Windows 7, the syntax is: netsh firewall add portopening TCP 8080 IISExpressWeb enable ALL

  1. Edit your IISExpress applicationhost.config file, typically found at your Documents\IISExpress\config\applicationhost.config. Find your site under sites, and add a binding to the port using your machine name, e.g.

  2. Startup IISExpress with Visual Studio, hit your URL from a browser on your Mac/VM Host, e.g. http://windows:8080

  3. Revel in your magnificence.

More info here: http://stackoverflow.com/questions/3313616/iis-express-enable-external-request http://stackoverflow.com/questions/5442551/iisexpress-returns-a-503-error-from-remote-machines http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx

Ref: https://gist.github.com/justingarrick/6322779