ajax調査

qiita.com

qiita.com

techblog.yahoo.co.jp

ajax

@{
    ViewBag.Title = "Json - Index";
}

<h2>Json - Index</h2>

<p><input type="button" id="jsexe0" value="JS実行" /></p>
<p><input type="button" id="jsexe1" value="JsonAction実行1" /></p>
<p><input type="button" id="jsexe2" value="JsonAction実行2" /></p>
<p><input type="button" id="jsexe3" value="JsonAction実行3" /></p>
<p><input type="button" id="jsexe4" value="JsonAction実行4" /></p>

@section scripts {
    
    <script type="text/javascript">
        $(function()
        {
            // -------------------- jsonファイルの読み込み、ファイルをルートへ配置
            $("#jsexe0").on('click', function () {
                console.log("jsexe1 start");
                
                // for
                $.getJSON("../test.json", function (data) {
                    for (var i in data) {
                        console.log(data[i].div);
                        for (var j in data[i].member) {
                            console.log(data[i].member[j].name + " - " + data[i].member[j].age);
                        }
                    }
                })

                // each
                $.getJSON("../test.json", function (data) {
                    $.each(data, function (i, obj) {
                        var div = obj.div;
                        console.log(div)
                        var member = obj.member;
                        $.each(member, function (j, m) {
                            console.log(m.name + "-" + m.age)
                        });
                    })
                })
            });

            // -------------------- Jsonデータの取得確認(単純なデータ)
            $("#jsexe1").on('click', function () {
                //alert("jsexe2");
                $.ajax(
                    {
                        url: "/Json/TestJsonFunc1",
                        type: 'POST',
                        data: { foo: "bar" },   // dummy
                        dataType: 'json',
                        contentType: 'application/json',
                        error: function () { },
                        complete: function (data) {
                            console.log(data.responseText);
                            var list = data.responseJSON;

                            $.each(list, function (index, value) {
                                console.log(value.ID + '_' + value.Name);
                            });
                        },
                    }
                );
            });

            // -------------------- Jsonデータの取得確認(階層データ)
            $("#jsexe2").on('click', function () {
                $.ajax(
                    {
                        url: "/Json/TestJsonFunc2",
                        type: 'POST',
                        data: { foo: "bar" },   // dummy
                        dataType: 'json',
                        contentType: 'application/json',
                        error: function () { },
                        complete: function (data) {
                            var cp = data.responseJSON;
                            console.log(cp);

                            $.each(cp, function(i, d){
                                console.log(d.div);
                                var mem = d.member;
                                $.each(mem, function(j, m){
                                    console.log(m.name + "-" + m.age);
                                })
                            })
                        },
                    }
                );
            });

            // -------------------- フロントで単純なJsonデータを生成、送信
            $("#jsexe3").on('click', function () {

                var foo = {};
                foo.Title = "botw";
                foo.Count = 1000;

                // javascriptオブジェクトをjson文字列へ変換
                var postData = JSON.stringify(foo);

                // 文字列をJSONオブジェクトへ変換
                var revFoo = JSON.parse(postData);
                console.log("Title:" + revFoo.Title);
                console.log("Count:" + revFoo.Count);

                $.ajax(
                    {
                        url: "/Json/TestJsonFunc3",
                        type: 'POST',
                        data: postData,
                        dataType: 'json',
                        contentType: 'application/json',
                        error: function () { },
                        complete: function (data) {
                            console.log(data.responseJSON);

                            // 文字列をJSONオブジェクトへ変換
                            console.log(JSON.parse(data.responseText));
                        },
                    }
                );
            });

            // -------------------- フロントで階層データを生成、送信
            $("#jsexe4").on('click', function () {

                var foo = {};
                foo.Title = "botw";
                foo.Count = 1000;
                foo.Contents = []
                foo.Contents.push("c-1")
                foo.Contents.push("c-2")

                // javascriptオブジェクトをjson文字列へ変換
                var postData = JSON.stringify(foo);

                $.ajax(
                    {
                        url: "/Json/TestJsonFunc4",
                        type: 'POST',
                        data: postData,
                        dataType: 'json',
                        contentType: 'application/json',
                        error: function () { },
                        complete: function (data) {
                            console.log(data.responseJSON);
                        },
                    }
                );
            });

        });

    </script>
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using System.Diagnostics;

namespace MvcLearn.Controllers
{
    public class JsonController : Controller
    {
        // GET: Json
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult TestJsonFunc1()
        {
            IList<object> objCollection = new List<object>(){
                new { ID = 10, Name = "aoki" },
                new { ID = 11, Name = "mukai" },
                new { ID = 12, Name = "romo" }
            };

            return new JsonResult() { Data = objCollection, ContentEncoding = System.Text.Encoding.UTF8, ContentType = @"application/json" };
        }

        [HttpPost]
        public ActionResult TestJsonFunc2()
        {
            var TestData = new List<object>() {
                new {
                    div = "営業部",
                    member = new List<object>(){
                        new { name = "saito",   age=20 },
                        new { name = "hashima", age=21 },
                        new { name = "shino",   age=22 }
                    }
                },
                new {
                    div = "営業部2",
                    member = new List<object>(){
                        new { name = "saito",   age=20 },
                        new { name = "hashima", age=21 },
                        new { name = "shino",   age=22 }
                    }
                }
            };

            return new JsonResult() { Data = TestData, ContentEncoding = System.Text.Encoding.UTF8, ContentType = @"application/json" };
        }

        [HttpPost]
        public ActionResult TestJsonFunc3(MvcLearn.Models.JsonViewModel model)
        {
            // json受信確認
            Debug.WriteLine("Title:" + model.Title);
            Debug.WriteLine("Count:" + model.Count);

            var TestData = new
            {
                div = "営業部",
                address = "東京都千代田区一ツ橋",
            };

            return new JsonResult() { Data = TestData, ContentEncoding = System.Text.Encoding.UTF8, ContentType = @"application/json" };
        }

        [HttpPost]
        public ActionResult TestJsonFunc4(MvcLearn.Models.JsonViewModel2 model)
        {
            // json受信確認
            Debug.WriteLine("Title:" + model.Title);
            Debug.WriteLine("Count:" + model.Count);
            foreach (var item in model.Contents)
            {
                Debug.WriteLine("Contents:" + item);
            }

            var TestData = new
            {
                div = "営業部",
                address = "東京都千代田区一ツ橋",
            };

            return new JsonResult() { Data = TestData, ContentEncoding = System.Text.Encoding.UTF8, ContentType = @"application/json" };
        }
    }
}

コントローラ

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;

namespace WebApiLearn.Controllers
{
    // 取得 :単一、複数データ取得
    // 登録、更新、削除:IHttpActionResultがわかりやすい、モデルの検証もFW側で対応している
    // model検証エラー badrequestで返す、詳細はmodelでわかる
    // それ以外のアプリケーションエラー? 200で返す、カスタムのエラーを設定でOK(詳細は通知する必要はない)

    public class MyParameter
    {
        public string Category { get; set; }
        public string Number { get; set; }
    }

    public class Person
    {
        // 属性とか
        [Required]
        [MaxLength(100)]
        public string Name { get; set; }

        [Required]
        [Range(1,3000, ErrorMessage = "{0} は {1} から {2} の範囲で指定してください")]
        public string Number { get; set; }

        // 別名
        [JsonProperty("birth_day")]
        [Required]
        public DateTime Birthday { get; set; }
    }

    public class MyResponseData
    {
        public string Result { get; set; }
        public IEnumerable<Person> persons { get; set; }
    }

    public class CustomersController : ApiBaseController
    {
        //[HttpGet]
        //public string Get([FromUri]MyParameter paramter, string id)
        //{

        //    return id + " - " + paramter.Category + " - " + paramter.Number;
        //}

        [HttpPost]
        //[Route("api/customers/entry2/v1")]
        [Route("api/v1/customers/entry2")]
        public Person EntryPerson2(Person person)
        {
            // モデル検証エラー時にValidationFilterAttributeにより下記を返す
            //{
            //    "message": "要求は無効です。",
            //    "modelState":{
            //        "person.Name":[
            //        "Name フィールドが必要です。"
            //    ]
            //}

            return new Person { Name = person.Name, Number = person.Number, Birthday = person.Birthday };
        }

        [HttpPost]
        [Route("api/customers/entry/v1")]
        public IHttpActionResult EntryPerson(Person person)
        {
            // JOSNで設定した値を取得
            //{
            //  name: "sakamoto",
            //  number: "10",
            //  birthday: "2000/1/1"
            //}

            // ValidationFilterAttributeへ移動
            //if (!ModelState.IsValid)
            //{
            //    return BadRequest(ModelState);
            //}

            // モデル検証エラー時にValidationFilterAttributeにより下記を返す
            //{
            //    "message": "要求は無効です。",
            //    "modelState":{
            //        "person.Name":[
            //        "Name フィールドが必要です。"
            //    ]
            //}


            // リクエストのJSONのキーは大文字・小文字を見ない?
            System.Diagnostics.Debug.WriteLine(person.Name + "-" + person.Number + "-" + person.Birthday.ToString());

            // IHttpActionResultの返値
            if (false)
            {
                return NotFound();
            }
            else
            {
                return Ok(new Person { Name = person.Name, Number = person.Number, Birthday = person.Birthday });
            }
        }

        [HttpGet]
        [Route("api/customers/resmsg/v1")]
        public HttpResponseMessage ResMsg()
        {
            if (false)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound);
            }
            else
            {
                return this.Request.CreateResponse(HttpStatusCode.OK);
            }

            //return this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "データを取得できませんでした。");
        }

        [HttpGet]
        [Route("api/customers/resexmsg/v1")]
        public HttpResponseMessage ResExMsg()
        {
            throw new HttpResponseException(this.Request.CreateResponse(HttpStatusCode.NotFound));
        }

        // stringを返す
        [HttpGet]
        //[Route("api/customers/name/v1/{id}")]
        [Route("api/v1/customers/name/{id}")]
        public string GetName(int id)
        {
            System.Diagnostics.Trace.TraceInformation(string.Format("id:{0}", id));
            System.Diagnostics.Trace.TraceWarning(string.Format("id:{0}", id));
            System.Diagnostics.Trace.TraceError(string.Format("id:{0}", id));
            return "kobayasi";
        }

        // PersonをJSONで返す
        [HttpGet]
        [Route("api/customers/person/v1/{id}")]
        public Person GetPerson(int id)
        {
            return new Person { Name = "niru", Number = "3", Birthday = DateTime.Parse("2000/1/2") };
        }

        // コレクションを返す
        [HttpGet]
        [Route("api/customers/persons/v1")]
        public IEnumerable<Person> GetAllPersons()
        {
            var list = new List<Person>()
            {
                new Person {Name = "kato", Number="2", Birthday=DateTime.Parse("2000/1/2")  },
                new Person {Name = "niru", Number="3", Birthday=DateTime.Parse("2000/1/2")  }
            };

            return list;
        }

        // MyResponseDataにPersonを設定、JSONで返す
        [HttpGet]
        [Route("api/customers/persons_res/v1")]
        public MyResponseData GetAllPersonsRes()
        {
            var list = new List<Person>()
            {
                new Person {Name = "kato", Number="2", Birthday=DateTime.Parse("2000/1/2")  },
                new Person {Name = "niru", Number="3", Birthday=DateTime.Parse("2000/1/2")  }
            };

            MyResponseData r = new MyResponseData();
            r.Result = "OK";
            r.persons = list;

            return r;
        }

        // 匿名型をJSONで返す
        [HttpGet]
        [Route("api/customers/persons_object/v1")]
        public object GetAllPersonsObject()
        {
            var list = new List<Person>()
            {
                new Person {Name = "kato", Number="2", Birthday=DateTime.Parse("2000/1/2")  },
                new Person {Name = "niru", Number="3", Birthday=DateTime.Parse("2000/1/2")  }
            };

            return new
            {
                result = "OK",
                persons = list
            };
        }

        [HttpGet]
        [Route("api/customers/exception_test/v1")]
        public IHttpActionResult ExceptionTest()
        {
            throw new Exception("テスト例外発生");
        }

    }
}

GlobalHandleErrorAttribute

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net;
using System.Diagnostics;


namespace MvcLearn.Extensions
{
    public class GlobalHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            // TODO ログを出力
            //LogUtil.LogControllerError(filterContext);
            Debug.WriteLine(filterContext.Exception.Message.ToString() 
                + Environment.NewLine
                + filterContext.Exception.StackTrace);

            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                /// Application_Errorは呼ばれない
                HandleAjaxRequestException(filterContext);
            }
            else
            {
                // custom errorが有効でなければ
                // base.OnException()でExceptionHandledがtrueにならないので
                // Application_Errorも呼ばれる
                base.OnException(filterContext);
            }
        }

        private void HandleAjaxRequestException(ExceptionContext filterContext)
        {
            if (filterContext.ExceptionHandled)
            {
                return;
            }

            filterContext.Result = new JsonResult
            {
                Data = new
                {
                    Message = filterContext.Exception.ToString(),
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                }
            };

            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    }
}

Application_Error(

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Security;
using System.Security.Principal;

namespace MvcLearn
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            // 認証情報を格納した Cookie を取得
            var authCookie = this.Request.Cookies[FormsAuthentication.FormsCookieName];

            // Cookie が 存在する場合
            if (authCookie != null && !string.IsNullOrEmpty(authCookie.Value))
            {
                // Cookie から 認証情報 を復元
                var ticket = FormsAuthentication.Decrypt(authCookie.Value);
                var identity = new GenericIdentity(ticket.Name, "Single Sing-On");
                var pricinpal = new GenericPrincipal(identity, new string[] { });
                HttpContext.Current.User = pricinpal;
            }
        }

        protected void Application_Error(object sender, EventArgs e)
        {
            if (Server != null)
            {
                var ex = Server.GetLastError();
                if (ex != null)
                {
                    if (ex is HttpException &&
                        ((HttpException)ex).GetHttpCode() == (int)HttpStatusCode.NotFound)
                    {
                        /// NotFoundを相手にするとログが大変になるので無視
                        return;
                    }

                    /// CustomErrorが無効な場合は
                    /// Controller内でおきた例外が二重にログ出力されてしまうことに注意。
                    /// CustomErrorが有効な場合は
                    /// Controller外でおきた例外のみここでログ出力される。
                    
                    // TODO ログ出力
                    Debug.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
                }
            }
        }
    }

}