ASP.NET MVC Windowsフォームからのリクエスト

概要

クライアント側がブラウザではなく、Windowsフォームを使用する例

GET

※MVCプロジェクト
namespace MyMVC.Controllers
{
 クライアントからのリクエストを制御
 public class TestController : Controller
 {
  public string Do(string prm)
  {
   ActionResult型でなく、文字列型を返す
   return prm;
  }
 }
}

クライアントからのパラメータの振り分け先設定
namespace MyMVC
{
 public class RouteConfig
 {
  public static void RegisterRoutes(RouteCollection routes)
  {
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   
   routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{prm}",
    defaults: new { controller = "Test", action = "Do", prm = UrlParameter.Optional }
   );
  }
 }
}

※Windowsフォームプロジェクト
WebRequest作成
var req = WebRequest.Create(@"http://localhost:12345/Test/Do/AAA");
本来はブラウザで指定するURLをWebRequestに設定
(AAAはパラメータ)
WebResponse作成
var res = req.GetResponse();
応答データ受信の為のStreamを取得
Stream st = res.GetResponseStream();
文字コード指定、StreamReader作成
StreamReader sr = new StreamReader(st, Encoding.UTF8);
データ受信
string htmlSource = sr.ReadToEnd();
MessageBox.Show(htmlSource);
→AAA
終了処理
sr.Close();
st.Close();
res.Close();

POST

WebRequestの作成
WebRequest req = WebRequest.Create("http://localhost:12345/Test/Do");
本来はブラウザで指定するURLをWebRequestに設定
POST送信する文字列をバイト型配列に変換
byte[] postDataBytes = Encoding.ASCII.GetBytes("AAA");

メソッドにPOSTを指定
req.Method = "POST";
ContentTypeを"application/x-www-form-urlencoded"に
req.ContentType = "application/x-www-form-urlencoded";
POST送信するデータの長さを指定
req.ContentLength = postDataBytes.Length;
POST送信の為のStreamを取得
Stream reqStream = req.GetRequestStream();
送信するデータ書き込み
reqStream.Write(postDataBytes, 0, postDataBytes.Length);
reqStream.Close();
リクエストメッセージ取得
WebResponse res = req.GetResponse();
↑ 受信データからStreamを取得
Stream resStream = res.GetResponseStream();
読み込み
StreamReader sr = new StreamReader(resStream, Encoding.GetEncoding("shift_jis");
MessageBox.Show(sr.ReadToEnd());
→AAA
終了処理
sr.Close();

※MVCプロジェクト
namespace MyMVC.Controllers
{ 
 クライアントからのリクエストを制御
 public class TestController : Controller
 {
  [HttpPost]
  public string Do()
  {
   Request.InputStream.Position = 0;
   using (StreamReader reader = new StreamReader(Request.InputStream, Encoding.UTF8))
   {
    string output = reader.ReadToEnd();
    ActionResult型でなく、文字列型を返す
    return output;
   }
  }
 }
}

ASP.NET MVC LINQ to Entities

LINQ

統合言語クエリー
Language Integrated Query
データベース、データセット、エンティティ、XML、配列、オブジェクト等、
プログラム内のデータに対する統一されたアクセス方法

LINQ to Entities

EntityDataModelに対するLINQ

実例

※モデル、コンテキストを用意しておく(ASP.NETMVC流れ参照)
private ArticleContext _db = new ArticleContext();

public ActionResult Search(string keyword, bool? released)
{

from句
var articles = from b in _db.Article select b;
var articles = _db.Articles .Select(a => a.Title);

select句
var articles = from b in _db.Article
  select new ArticleView
  {
    Title = b.Title.Substring(0, 10),
    ViewCount = (int)Math.Ceiling(b.ViewCount/ 1000.0),
    Released = (b.Released ? “公開中” : “公開予定”)
  };

別クラス(Model/ArticleView.cs)
public class ArticleView
{
  public string Title { get; set; }
  public int ViewCount { get; set; }
  public string Released { get; set; }
}

//匿名クラスを利用(「匿名クラス」参照)
var articles = from b in _db.Article
  select new
  {
    b.Title.Substring(0, 10),
    b.ViewCount,
    b.Released
  };

var articles = _db.Article
  .Select(b => new ArticleView
  {
    Title = b.Title.Substring(0, 10),
    ViewCount = (int)Math.Ceiling(b.ViewCount/ 1000.0),
    Released = (b.Released ? “公開中” : “公開予定”)
  });

別クラス(Model/ArticleView.cs)
public class ArticleView
{
  public string Title { get; set; }
  public int ViewCount { get; set; }
  public string Released { get; set; }
}

where句
var articles = from b in _db.Article
  where a.Title == "title1"
  selectb;
var articles = _db.Articles
  .Where(a => a.Title == "title1");
  .Select(a=>a.Title);

orderby句
var articles = from b in _db.Article
  orderby b.Published ascending, b.Title descending
  select b;
var articles = _db.Articles
  .OrderBy(b => b.Published)
  .ThenByDescending(b => b.Title);

var articles = _db.Articles
  .OrderByDescending(b => b.Published)
  .ThenBy(b => b.Title);

第一キー
OrderBy(昇順)/OrderByDescending(降順)
第二キー以降
ThenBy(昇順)/ThenDescending(降順)

contain()

//keywordを含むデータを抽出

if (!string.IsNullOrEmpty(keyword) ){
  var articles = from b in _db.Article
    where b.Title.Contains(keyword) select b;
}
if (!string.IsNullOrEmpty(keyword) ){
  articles = articles.Where(a => a.Title.Contains(keyword));
}

==

//true/falseであるデータを抽出

if ( released.HasValue && released.Value) {
  var articles = from b in _db.Article
    where b.release == true select b;
};
if ( released.HasValue && released.Value) {
  articles = articles.Where(a => a.Released);
  articles = articles.Where(a => a.Released == true);
};

Distinct()
var articles = (from a in _db.Article select a.Title).Distinct();
無し

Skip()/Take()
//先頭から5レコードは飛ばす(取得しない)
var articles = (from a in _db.Article select a.Title).Skip(5);
//先頭から5レコードのみ取得する
var articles = (from a in _db.Article select a.Title).Take(5);
//先頭から5レコード飛ばし、6レコード目から5レコードのみ取得する
var articles = (from a in _db.Article select a.Title).Skip(5).Take(5);
無し

First()/FirstOrDefault()
//先頭レコードのみ取得する(~).Take(1)と同じ)
var articles = (from a in _db.Article select a.Title).First();
//先頭レコードのみ取得する。該当データ無しの場合はデフォルト値を取得する
var articles = (from a in _db.Article select a.Title).FirstOrDefault();
無し

group by句
var articles = from a in _db.Article group a by a.Category;

※View
@model IEnumerable<IGrouping<string , ASPNET_MVC_DB.Models.Article>>

<body>
  //elmGrpにはカテゴリーのグループ結果が入る
  @foreach (var elmGrp in Model)
  {
    @elmGrp.Key<br/>

    //elmにはグループ内の要素が入る
    foreach (var elm in elmGrp) {
      @elm.Title<br/>
    }
    <br/>
  }
</body>

⇒結果:
CategoryA
Title1
Title2

CategoryB
Title3
Title4

CategoryC
Title5

グループ結果を絞る場合(Title、ViewCount)
var articles = from a in _db.Article
  group new ArticleView { Title = a.Title, ViewCount = a.ViewCount }
  by a.Category;

複数列でグループ化する場合(Title、ViewCount)
var articles = from a in _db.Article
  group a by new ArticleView { Title = a.Title, ViewCount = a.ViewCount };

別クラス(Model/ArticleView.cs)
public class ArticleView
{
  public string Title { get; set; }
  public int ViewCount { get; set; }
  public string Released { get; set; }
}

var articles = _db.Article.GroupBy(a => a.Category);

※View
@model IEnumerable<IGrouping<string , ASPNET_MVC_DB.Models.Article>>

<body>
  //elmGrpにはカテゴリーのグループ結果が入る
  @foreach (var elmGrp in Model)
  {
    @elmGrp.Key<br/>

    //elmにはグループ内の要素が入る
    foreach (var elm in elmGrp) {
      @elm.Title<br/>
    }
    <br/>
  }
</body>

⇒結果:
CategoryA
Title1
Title2

CategoryB
Title3
Title4

CategoryC
Title5

グループ結果を絞る場合(Title、ViewCount)
var articles = _db.Article
  .GroupBy( a => a.Title , a => new ArticleView { Title = a.Title, ViewCount = a.ViewCount });

複数列でグループ化する場合(Title、ViewCount)
var articles = _db.Article
  .GroupBy( a => new ArticleView { Title = a.Title, ViewCount = a.ViewCount });

別クラス(Model/ArticleView.cs)
public class ArticleView
{
  public string Title { get; set; }
  public int ViewCount { get; set; }
  public string Released { get; set; }
}


  
  return View(articles);
}

ASP.NET MVC ルーティング

グローバルアプリケーションファイル

Global.asax
アプリケーション共通で起動時に実行するイベントを設定
public class MvcApplication : System.Web.HttpApplication
{
  protected void Application_Start()
  {
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    
    //RouteConfig.RegisterRoutes()メソッドを実行する
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    
    BundleConfig.RegisterBundles(BundleTable.Bundles);
  }
}

ルート情報定義

通常アプリケーション起動時に呼び出す。
App_Start/RouteConfig.cs(ASP.NET MVC3以降)
public class RouteConfig
{
  public static void RegisterRoutes(RouteCollection routes)
  {
    routes.MapRoute(
      name: "Default",
      url: "{controller}/{action}/{id}/{prm1}/{prm2}",
      // ↑ urlに対するデフォルト値
      defaults: new {
        controller = "Home",
        action = "Index",
        id = UrlParameter.Optional,
        prm1 = "100",
        prm2 = "AAA" }
    );
  }
}

ASP.NET MVC ActionResult

ViewResult

public ActionResult Index()
{
  return View();
}
↓ と同じ
ViewResult vr = new ViewResult();
vr.ViewBag.Msg = "aaa";
return vr;

PartialViewResult

メソッド:PartialView()

RedirectResult

public ActionResult Index()
{
  return Redirect("http://www.~");
  ※return Redirect("~/Next/Index"); も可
}
↓ と同じ
RedirectResult rr = new RedirectResult(url:"http://www.~");
return rr;

RedirectToRouteResult

return RedirectToAction(
  actionName: "Index",
  controllerName: "Next",
  routeValues: new { id = "1", charset = "utf8" }
  );

return RedirectToRoute(
  routeName: "Default",
  routeValues: new {
    contoroller = "Next",
    action = "Index",
    id = "1",
    charset = "utf8"
  }
);

ContentResult

メソッド:Content()

FilePathResult

メソッド:File()

ASP.NET MVC 外部レイアウト/部分ビュー

外部レイアウト

通常のView(レイアウト使用無し)

@{
  Layout = null;
}
<!DOCTYPE html>
<html>
<head>
  <title>Index1</title>
</head>
<body>
  内容
</body>
</html>

※外部レイアウト使用

(Views/Index.cshtml)
@{
  //レイアウトファイル名は「_」で開始されている事
  Layout = "~/Views/Shared/_Layout.cshtml";
}
内容…①

レイアウトを使用するとViewに<html>や<body>タグが表示されない。
レイアウトファイルに記載されたタグが使用される。
この場合、Viewでの編集領域は、↓ レイアウトファイルにおける@RenderBody部分に格納される。

※レイアウトファイル
(Views/Shared/_Layout.cshtml)
<!DOCTYPE html>
<html>
<head>
  <title>@ViewBag.Title</title>
  <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
  <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
</head>
<body>
  @RenderBody() …①の内容はここに表示される
</body>
</html>

部分ビュー

↓ View(レイアウト使用でも不使用でも可)
//部分ビューの読み込み
@Html.Partial(partialViewName:"_Layout")
⇒外部ファイルが↑ 部分に読み込まれる。