QA@IT
«回答へ戻る

先頭に追記したことを記述と、ASP.NET MVCのバージョン確認コードを消し忘れてたので、説明コメントを追加。

5599
+※ うしろにASP.NET MVCで試したものを追記しました。
+
 javascript部分しか確認してません。
 とりあえず現状からであれば、successの中でjavascriptでsubmitして、
 ボタンのイベント自体はキャンセルしてしまうという手があると思います。
 </head>
 <body>
 <div ng-app="app" ng-controller="MainCtrl as app">
+    @* ASP.NET MVCのバージョン確認 *@
     @ViewBag.Version
 
     @using (Html.BeginForm( "Main", "Test", null,

※ うしろにASP.NET MVCで試したものを追記しました。

javascript部分しか確認してません。
とりあえず現状からであれば、successの中でjavascriptでsubmitして、
ボタンのイベント自体はキャンセルしてしまうという手があると思います。

イベントオブジェクト($event)をng-clickに追加

    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)" /><br />

イベントハンドラの修正

    $scope.DoAuthenticate = function(e) {  // 引数追加
     e.preventDefault();                   // 追加

     $http({
      method : 'GET',
      url : "認証用のurl"
     }).success(function(data, status, headers, config) {
      if (!data) {
       $scope.loginResult = "ログインに失敗しました";
       return;   // 追加
      }
      document.getElementsByTagName('form')[0].submit(); // 追加:formは 1つしかないと仮定してます
     }).error(function(data, status, headers, config) {
      console.log(status);
     });

     return false; // 追加
    };

スクリプトからsubmitしているのでユーザーアクションとみなされないので例えば target="_blank"とかだとポップアップブロックに引っかかるなど、制限がかかる場合があります。

老婆心ながら、このスクリプトからもわかるように、api呼ばずにsubmitできてしまう(
javascript:document.getElementsByTagName('form')[0].submit(); とか)
ので、そのあたりは注意してください。

具体的なコードは考えてないですが、formのng-submitで拾った方が良さそうな気はしますが、それだとsubmitしようが無くなるんですかね?

ブラウザとangularjsのバージョンは書いておいてほしいところです。特にangularはバージョン間の差分がそれなりにあるので。

jsbinでのデモ (自分が確認するために書いたもの。説明が長いので試してみたいときだけどうぞ)

※ jsbin.comの他、ボタン押下後、最後に http://posttestserver.comに実際にPOSTしてます。
(ソース見るだけならPOSTは発生しません。)
※ 実行するときは(出力画面が別画面じゃないとリフレッシュされたのわからないので)OUTPUTペインの分離ボタン押してから実行してください

qait9560.png

https://jsbin.com/yurayanaqi/edit?html,js,console,output

いろいろ:

  • 認証の$http部分は偽物のFactoryにしていて、2秒待って返すだけです。
  • .success .error スタイルの作り方が出てこなかったんで、promiseになってます。thenの第一引数がsuccessで、第二引数がerror。
  • success, errorの引数が違います(statusやdataは response.status, response.data に。判定につかっているdata以外は気にしてません)。
  • httpDummyのfailureTest とか errorTestをtrueにすると、エラーっぽい挙動とdataを返さない挙動になります。
  • consoleにちょびちょびログ吐いてます。
  • ChromeとIE11で確認しました。

追記

まず先に、ng-sugmitHtml.BeginFormng_submitとして属性を追加してあげれば使えます。
以下のサンプルにもボタンを追加して、ng-submitの動作を見ています。

Visual Studio 2013 pro, ASP.NET MVC 5.2.2, Chrome 45, AngularJS 1.3.0 公式から

ASP.NET Webアプリケーション - MVC のみチェック

で、以下の様なソースです。
ng_submit以外は JSBinの時と同じです。 2秒待ってsuccessの処理を行います。

jsBinに挙げたやつでは、関数名をsubmitFormに変えていたので、もしそっちからスクリプトだけコピペしてたら上手くいかないです。こっちに書いたのは提示ソースにそろえてるはずですが。

  • Views/Test/Index.cshtml
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
<div ng-app="app" ng-controller="MainCtrl as app">
    @* ASP.NET MVCのバージョン確認 *@
    @ViewBag.Version

    @using (Html.BeginForm( "Main", "Test", null,
        FormMethod.Post, new {ng_submit = "angularSubmit($event)"})){
        <table>
            <tr>
                <th>ユーザーID</th>
                <td><input type="text" name="UserCode" ng-model="UserCode"/></td>
            </tr>
            <tr>
                <th>パスワード</th>
                <td><input type="text" name="UserPassword" ng-model="UserPassword"/></td>
            </tr>
            <tr>
                <td colspan="2" style="text-align: right;">
                    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)"/><br/>
                    {{loginResult}}<br/>
                    <input type="submit" value="ng-submit のテスト"/><br/>
                </td>
            </tr>
        </table>
    }
</div>
    <script src="~/Scripts/angular.js"></script>
    <script src="~/Scripts/app.js"></script>
</body>
</html>
  • Scripts/app.js
var app = angular.module('app', []);
app.constant('AUTH_API', 'http://example.com/auth');
app.controller('MainCtrl', function ($scope, AuthApiAlternate, AUTH_API) {

    $scope.DoAuthenticate = DoAuthenticate;
    $scope.angularSubmit = angularSubmit;
    $scope.loginResult = "angular is working";

    function DoAuthenticate(e) {
        e.preventDefault();

        var $http = AuthApiAlternate.httpDummy;
        $http({
            method: 'GET',
            url: AUTH_API
        }).then(function (response) {
            if (!response.data) {
                $scope.loginResult = "ログインに失敗しました";
            } else {
                $scope.loginResult = null;
                document.getElementsByTagName('form')[0].submit();
            }
        }, function (response) {
            console.log(response.status);
        });
        console.log('my dummy return results after 2 sec.');
        return false;
    }

    function angularSubmit() { // ng-submit用
        alert('ng-submit!');
    }
});

// $httpの代わり。jsbinの時と同じ。2 秒待って successになる。 failureTestやerrorTestをいじると挙動が変わる
app.factory('AuthApiAlternate', function ($q) {
    return { httpDummy: httpDummy };
    function httpDummy(opt) {
        var defer = $q.defer();
        var failureTest = false;
        var errorTest = false;
        console.log('url you specified :' + opt.url);
        setTimeout(function () {
            if (failureTest) {
                console.log('failure');
                defer.resolve({ status: 200 });
                return;
            }
            if (errorTest) {
                defer.reject({ status: 500, data: "something wrong happend" });
                return;
            }
            defer.resolve({ status: 200, data: 'You logged in.' });
            return;
        }, 2000);
        return defer.promise;
    }
});
  • Controllers/TestController.cs
namespace InjectSubmit.Controllers{

    /// <summary> qait 9560 </summary>
    public class TestController : Controller{
        // GET: Test
        public ActionResult Index(){
            ViewBag.Version = typeof(Controller).Assembly.GetName().Version.ToString();
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public String Main(){
            return "Post Success :" + Request.Form["userCode"];
        }
   }
}
※ うしろにASP.NET MVCで試したものを追記しました。

javascript部分しか確認してません。
とりあえず現状からであれば、successの中でjavascriptでsubmitして、
ボタンのイベント自体はキャンセルしてしまうという手があると思います。

イベントオブジェクト(`$event`)をng-clickに追加

```html
    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)" /><br />
```

イベントハンドラの修正

```javascript
    $scope.DoAuthenticate = function(e) {  // 引数追加
     e.preventDefault();                   // 追加
     
     $http({
      method : 'GET',
      url : "認証用のurl"
     }).success(function(data, status, headers, config) {
      if (!data) {
       $scope.loginResult = "ログインに失敗しました";
       return;   // 追加
      }
      document.getElementsByTagName('form')[0].submit(); // 追加:formは 1つしかないと仮定してます
     }).error(function(data, status, headers, config) {
      console.log(status);
     });

     return false; // 追加
    };
```

スクリプトからsubmitしているのでユーザーアクションとみなされないので例えば `target="_blank"`とかだとポップアップブロックに引っかかるなど、制限がかかる場合があります。

老婆心ながら、このスクリプトからもわかるように、api呼ばずにsubmitできてしまう( 
`javascript:document.getElementsByTagName('form')[0].submit();` とか)
ので、そのあたりは注意してください。

具体的なコードは考えてないですが、formのng-submitで拾った方が良さそうな気はしますが、それだとsubmitしようが無くなるんですかね?

ブラウザとangularjsのバージョンは書いておいてほしいところです。特にangularはバージョン間の差分がそれなりにあるので。

jsbinでのデモ (自分が確認するために書いたもの。説明が長いので試してみたいときだけどうぞ)

※ jsbin.comの他、ボタン押下後、最後に `http://posttestserver.com`に実際にPOSTしてます。
(ソース見るだけならPOSTは発生しません。)
※ 実行するときは(出力画面が別画面じゃないとリフレッシュされたのわからないので)OUTPUTペインの分離ボタン押してから実行してください

![qait9560.png](https://qa-atmarkit-image.s3.amazonaws.com/uploads/attached_image/image/121/qait9560.png)

https://jsbin.com/yurayanaqi/edit?html,js,console,output

いろいろ:

* 認証の$http部分は偽物のFactoryにしていて、2秒待って返すだけです。
* `.success` `.error` スタイルの作り方が出てこなかったんで、promiseになってます。thenの第一引数がsuccessで、第二引数がerror。
* success, errorの引数が違います(statusやdataは response.status, response.data に。判定につかっているdata以外は気にしてません)。
* httpDummyのfailureTest とか errorTestをtrueにすると、エラーっぽい挙動とdataを返さない挙動になります。
* consoleにちょびちょびログ吐いてます。
* ChromeとIE11で確認しました。

---

## 追記

まず先に、`ng-sugmit`は `Html.BeginForm` で `ng_submit`として属性を追加してあげれば使えます。
以下のサンプルにもボタンを追加して、`ng-submit`の動作を見ています。

Visual Studio 2013 pro, ASP.NET MVC 5.2.2, Chrome 45, AngularJS 1.3.0 [公式から]( https://code.angularjs.org/1.3.0/ )

ASP.NET Webアプリケーション - MVC のみチェック

で、以下の様なソースです。
ng_submit以外は JSBinの時と同じです。 2秒待ってsuccessの処理を行います。

jsBinに挙げたやつでは、関数名を`submitForm`に変えていたので、もしそっちからスクリプトだけコピペしてたら上手くいかないです。こっちに書いたのは提示ソースにそろえてるはずですが。


* Views/Test/Index.cshtml

```html
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
<div ng-app="app" ng-controller="MainCtrl as app">
    @* ASP.NET MVCのバージョン確認 *@
    @ViewBag.Version

    @using (Html.BeginForm( "Main", "Test", null,
        FormMethod.Post, new {ng_submit = "angularSubmit($event)"})){
        <table>
            <tr>
                <th>ユーザーID</th>
                <td><input type="text" name="UserCode" ng-model="UserCode"/></td>
            </tr>
            <tr>
                <th>パスワード</th>
                <td><input type="text" name="UserPassword" ng-model="UserPassword"/></td>
            </tr>
            <tr>
                <td colspan="2" style="text-align: right;">
                    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)"/><br/>
                    {{loginResult}}<br/>
                    <input type="submit" value="ng-submit のテスト"/><br/>
                </td>
            </tr>
        </table>
    }
</div>
    <script src="~/Scripts/angular.js"></script>
    <script src="~/Scripts/app.js"></script>
</body>
</html>
```

* Scripts/app.js

```javascript
var app = angular.module('app', []);
app.constant('AUTH_API', 'http://example.com/auth');
app.controller('MainCtrl', function ($scope, AuthApiAlternate, AUTH_API) {

    $scope.DoAuthenticate = DoAuthenticate;
    $scope.angularSubmit = angularSubmit;
    $scope.loginResult = "angular is working";

    function DoAuthenticate(e) {
        e.preventDefault();

        var $http = AuthApiAlternate.httpDummy;
        $http({
            method: 'GET',
            url: AUTH_API
        }).then(function (response) {
            if (!response.data) {
                $scope.loginResult = "ログインに失敗しました";
            } else {
                $scope.loginResult = null;
                document.getElementsByTagName('form')[0].submit();
            }
        }, function (response) {
            console.log(response.status);
        });
        console.log('my dummy return results after 2 sec.');
        return false;
    }

    function angularSubmit() { // ng-submit用
        alert('ng-submit!');
    }
});

// $httpの代わり。jsbinの時と同じ。2 秒待って successになる。 failureTestやerrorTestをいじると挙動が変わる
app.factory('AuthApiAlternate', function ($q) {
    return { httpDummy: httpDummy };
    function httpDummy(opt) {
        var defer = $q.defer();
        var failureTest = false;
        var errorTest = false;
        console.log('url you specified :' + opt.url);
        setTimeout(function () {
            if (failureTest) {
                console.log('failure');
                defer.resolve({ status: 200 });
                return;
            }
            if (errorTest) {
                defer.reject({ status: 500, data: "something wrong happend" });
                return;
            }
            defer.resolve({ status: 200, data: 'You logged in.' });
            return;
        }, 2000);
        return defer.promise;
    }
});
```

* Controllers/TestController.cs

```cs
namespace InjectSubmit.Controllers{

    /// <summary> qait 9560 </summary>
    public class TestController : Controller{
        // GET: Test
        public ActionResult Index(){
            ViewBag.Version = typeof(Controller).Assembly.GetName().Version.ToString();
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public String Main(){
            return "Post Success :" + Request.Form["userCode"];
        }
   }
}
```

ASP.NETでのサンプルの追加

5599
 
 ブラウザとangularjsのバージョンは書いておいてほしいところです。特にangularはバージョン間の差分がそれなりにあるので。
 
-
 jsbinでのデモ (自分が確認するために書いたもの。説明が長いので試してみたいときだけどうぞ)
 
 ※ jsbin.comの他、ボタン押下後、最後に `http://posttestserver.com`に実際にPOSTしてます。
 
 ![qait9560.png](https://qa-atmarkit-image.s3.amazonaws.com/uploads/attached_image/image/121/qait9560.png)
 
-
 https://jsbin.com/yurayanaqi/edit?html,js,console,output
 
 いろいろ:
 * httpDummyのfailureTest とか errorTestをtrueにすると、エラーっぽい挙動とdataを返さない挙動になります。
 * consoleにちょびちょびログ吐いてます。
 * ChromeとIE11で確認しました。
+
+---
+
+## 追記
+
+まず先に、`ng-sugmit`は `Html.BeginForm` で `ng_submit`として属性を追加してあげれば使えます。
+以下のサンプルにもボタンを追加して、`ng-submit`の動作を見ています。
+
+Visual Studio 2013 pro, ASP.NET MVC 5.2.2, Chrome 45, AngularJS 1.3.0 [公式から]( https://code.angularjs.org/1.3.0/ )
+
+ASP.NET Webアプリケーション - MVC のみチェック
+
+で、以下の様なソースです。
+ng_submit以外は JSBinの時と同じです。 2秒待ってsuccessの処理を行います。
+
+jsBinに挙げたやつでは、関数名を`submitForm`に変えていたので、もしそっちからスクリプトだけコピペしてたら上手くいかないです。こっちに書いたのは提示ソースにそろえてるはずですが。
+
+
+* Views/Test/Index.cshtml
+
+```html
+@{
+    Layout = null;
+}
+<!DOCTYPE html>
+<html>
+<head>
+    <meta name="viewport" content="width=device-width" />
+    <title>Index</title>
+</head>
+<body>
+<div ng-app="app" ng-controller="MainCtrl as app">
+    @ViewBag.Version
+
+    @using (Html.BeginForm( "Main", "Test", null,
+        FormMethod.Post, new {ng_submit = "angularSubmit($event)"})){
+        <table>
+            <tr>
+                <th>ユーザーID</th>
+                <td><input type="text" name="UserCode" ng-model="UserCode"/></td>
+            </tr>
+            <tr>
+                <th>パスワード</th>
+                <td><input type="text" name="UserPassword" ng-model="UserPassword"/></td>
+            </tr>
+            <tr>
+                <td colspan="2" style="text-align: right;">
+                    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)"/><br/>
+                    {{loginResult}}<br/>
+                    <input type="submit" value="ng-submit のテスト"/><br/>
+                </td>
+            </tr>
+        </table>
+    }
+</div>
+    <script src="~/Scripts/angular.js"></script>
+    <script src="~/Scripts/app.js"></script>
+</body>
+</html>
+```
+
+* Scripts/app.js
+
+```javascript
+var app = angular.module('app', []);
+app.constant('AUTH_API', 'http://example.com/auth');
+app.controller('MainCtrl', function ($scope, AuthApiAlternate, AUTH_API) {
+
+    $scope.DoAuthenticate = DoAuthenticate;
+    $scope.angularSubmit = angularSubmit;
+    $scope.loginResult = "angular is working";
+
+    function DoAuthenticate(e) {
+        e.preventDefault();
+
+        var $http = AuthApiAlternate.httpDummy;
+        $http({
+            method: 'GET',
+            url: AUTH_API
+        }).then(function (response) {
+            if (!response.data) {
+                $scope.loginResult = "ログインに失敗しました";
+            } else {
+                $scope.loginResult = null;
+                document.getElementsByTagName('form')[0].submit();
+            }
+        }, function (response) {
+            console.log(response.status);
+        });
+        console.log('my dummy return results after 2 sec.');
+        return false;
+    }
+
+    function angularSubmit() { // ng-submit用
+        alert('ng-submit!');
+    }
+});
+
+// $httpの代わり。jsbinの時と同じ。2 秒待って successになる。 failureTestやerrorTestをいじると挙動が変わる
+app.factory('AuthApiAlternate', function ($q) {
+    return { httpDummy: httpDummy };
+    function httpDummy(opt) {
+        var defer = $q.defer();
+        var failureTest = false;
+        var errorTest = false;
+        console.log('url you specified :' + opt.url);
+        setTimeout(function () {
+            if (failureTest) {
+                console.log('failure');
+                defer.resolve({ status: 200 });
+                return;
+            }
+            if (errorTest) {
+                defer.reject({ status: 500, data: "something wrong happend" });
+                return;
+            }
+            defer.resolve({ status: 200, data: 'You logged in.' });
+            return;
+        }, 2000);
+        return defer.promise;
+    }
+});
+```
+
+* Controllers/TestController.cs
+
+```cs
+namespace InjectSubmit.Controllers{
+
+    /// <summary> qait 9560 </summary>
+    public class TestController : Controller{
+        // GET: Test
+        public ActionResult Index(){
+            ViewBag.Version = typeof(Controller).Assembly.GetName().Version.ToString();
+            return View();
+        }
+
+        [AcceptVerbs(HttpVerbs.Post)]
+        public String Main(){
+            return "Post Success :" + Request.Form["userCode"];
+        }
+   }
+}
+```

javascript部分しか確認してません。
とりあえず現状からであれば、successの中でjavascriptでsubmitして、
ボタンのイベント自体はキャンセルしてしまうという手があると思います。

イベントオブジェクト($event)をng-clickに追加

    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)" /><br />

イベントハンドラの修正

    $scope.DoAuthenticate = function(e) {  // 引数追加
     e.preventDefault();                   // 追加

     $http({
      method : 'GET',
      url : "認証用のurl"
     }).success(function(data, status, headers, config) {
      if (!data) {
       $scope.loginResult = "ログインに失敗しました";
       return;   // 追加
      }
      document.getElementsByTagName('form')[0].submit(); // 追加:formは 1つしかないと仮定してます
     }).error(function(data, status, headers, config) {
      console.log(status);
     });

     return false; // 追加
    };

スクリプトからsubmitしているのでユーザーアクションとみなされないので例えば target="_blank"とかだとポップアップブロックに引っかかるなど、制限がかかる場合があります。

老婆心ながら、このスクリプトからもわかるように、api呼ばずにsubmitできてしまう(
javascript:document.getElementsByTagName('form')[0].submit(); とか)
ので、そのあたりは注意してください。

具体的なコードは考えてないですが、formのng-submitで拾った方が良さそうな気はしますが、それだとsubmitしようが無くなるんですかね?

ブラウザとangularjsのバージョンは書いておいてほしいところです。特にangularはバージョン間の差分がそれなりにあるので。

jsbinでのデモ (自分が確認するために書いたもの。説明が長いので試してみたいときだけどうぞ)

※ jsbin.comの他、ボタン押下後、最後に http://posttestserver.comに実際にPOSTしてます。
(ソース見るだけならPOSTは発生しません。)
※ 実行するときは(出力画面が別画面じゃないとリフレッシュされたのわからないので)OUTPUTペインの分離ボタン押してから実行してください

qait9560.png

https://jsbin.com/yurayanaqi/edit?html,js,console,output

いろいろ:

  • 認証の$http部分は偽物のFactoryにしていて、2秒待って返すだけです。
  • .success .error スタイルの作り方が出てこなかったんで、promiseになってます。thenの第一引数がsuccessで、第二引数がerror。
  • success, errorの引数が違います(statusやdataは response.status, response.data に。判定につかっているdata以外は気にしてません)。
  • httpDummyのfailureTest とか errorTestをtrueにすると、エラーっぽい挙動とdataを返さない挙動になります。
  • consoleにちょびちょびログ吐いてます。
  • ChromeとIE11で確認しました。

追記

まず先に、ng-sugmitHtml.BeginFormng_submitとして属性を追加してあげれば使えます。
以下のサンプルにもボタンを追加して、ng-submitの動作を見ています。

Visual Studio 2013 pro, ASP.NET MVC 5.2.2, Chrome 45, AngularJS 1.3.0 公式から

ASP.NET Webアプリケーション - MVC のみチェック

で、以下の様なソースです。
ng_submit以外は JSBinの時と同じです。 2秒待ってsuccessの処理を行います。

jsBinに挙げたやつでは、関数名をsubmitFormに変えていたので、もしそっちからスクリプトだけコピペしてたら上手くいかないです。こっちに書いたのは提示ソースにそろえてるはずですが。

  • Views/Test/Index.cshtml
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
<div ng-app="app" ng-controller="MainCtrl as app">
    @ViewBag.Version

    @using (Html.BeginForm( "Main", "Test", null,
        FormMethod.Post, new {ng_submit = "angularSubmit($event)"})){
        <table>
            <tr>
                <th>ユーザーID</th>
                <td><input type="text" name="UserCode" ng-model="UserCode"/></td>
            </tr>
            <tr>
                <th>パスワード</th>
                <td><input type="text" name="UserPassword" ng-model="UserPassword"/></td>
            </tr>
            <tr>
                <td colspan="2" style="text-align: right;">
                    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)"/><br/>
                    {{loginResult}}<br/>
                    <input type="submit" value="ng-submit のテスト"/><br/>
                </td>
            </tr>
        </table>
    }
</div>
    <script src="~/Scripts/angular.js"></script>
    <script src="~/Scripts/app.js"></script>
</body>
</html>
  • Scripts/app.js
var app = angular.module('app', []);
app.constant('AUTH_API', 'http://example.com/auth');
app.controller('MainCtrl', function ($scope, AuthApiAlternate, AUTH_API) {

    $scope.DoAuthenticate = DoAuthenticate;
    $scope.angularSubmit = angularSubmit;
    $scope.loginResult = "angular is working";

    function DoAuthenticate(e) {
        e.preventDefault();

        var $http = AuthApiAlternate.httpDummy;
        $http({
            method: 'GET',
            url: AUTH_API
        }).then(function (response) {
            if (!response.data) {
                $scope.loginResult = "ログインに失敗しました";
            } else {
                $scope.loginResult = null;
                document.getElementsByTagName('form')[0].submit();
            }
        }, function (response) {
            console.log(response.status);
        });
        console.log('my dummy return results after 2 sec.');
        return false;
    }

    function angularSubmit() { // ng-submit用
        alert('ng-submit!');
    }
});

// $httpの代わり。jsbinの時と同じ。2 秒待って successになる。 failureTestやerrorTestをいじると挙動が変わる
app.factory('AuthApiAlternate', function ($q) {
    return { httpDummy: httpDummy };
    function httpDummy(opt) {
        var defer = $q.defer();
        var failureTest = false;
        var errorTest = false;
        console.log('url you specified :' + opt.url);
        setTimeout(function () {
            if (failureTest) {
                console.log('failure');
                defer.resolve({ status: 200 });
                return;
            }
            if (errorTest) {
                defer.reject({ status: 500, data: "something wrong happend" });
                return;
            }
            defer.resolve({ status: 200, data: 'You logged in.' });
            return;
        }, 2000);
        return defer.promise;
    }
});
  • Controllers/TestController.cs
namespace InjectSubmit.Controllers{

    /// <summary> qait 9560 </summary>
    public class TestController : Controller{
        // GET: Test
        public ActionResult Index(){
            ViewBag.Version = typeof(Controller).Assembly.GetName().Version.ToString();
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public String Main(){
            return "Post Success :" + Request.Form["userCode"];
        }
   }
}
javascript部分しか確認してません。
とりあえず現状からであれば、successの中でjavascriptでsubmitして、
ボタンのイベント自体はキャンセルしてしまうという手があると思います。

イベントオブジェクト(`$event`)をng-clickに追加

```html
    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)" /><br />
```

イベントハンドラの修正

```javascript
    $scope.DoAuthenticate = function(e) {  // 引数追加
     e.preventDefault();                   // 追加
     
     $http({
      method : 'GET',
      url : "認証用のurl"
     }).success(function(data, status, headers, config) {
      if (!data) {
       $scope.loginResult = "ログインに失敗しました";
       return;   // 追加
      }
      document.getElementsByTagName('form')[0].submit(); // 追加:formは 1つしかないと仮定してます
     }).error(function(data, status, headers, config) {
      console.log(status);
     });

     return false; // 追加
    };
```

スクリプトからsubmitしているのでユーザーアクションとみなされないので例えば `target="_blank"`とかだとポップアップブロックに引っかかるなど、制限がかかる場合があります。

老婆心ながら、このスクリプトからもわかるように、api呼ばずにsubmitできてしまう( 
`javascript:document.getElementsByTagName('form')[0].submit();` とか)
ので、そのあたりは注意してください。

具体的なコードは考えてないですが、formのng-submitで拾った方が良さそうな気はしますが、それだとsubmitしようが無くなるんですかね?

ブラウザとangularjsのバージョンは書いておいてほしいところです。特にangularはバージョン間の差分がそれなりにあるので。

jsbinでのデモ (自分が確認するために書いたもの。説明が長いので試してみたいときだけどうぞ)

※ jsbin.comの他、ボタン押下後、最後に `http://posttestserver.com`に実際にPOSTしてます。
(ソース見るだけならPOSTは発生しません。)
※ 実行するときは(出力画面が別画面じゃないとリフレッシュされたのわからないので)OUTPUTペインの分離ボタン押してから実行してください

![qait9560.png](https://qa-atmarkit-image.s3.amazonaws.com/uploads/attached_image/image/121/qait9560.png)

https://jsbin.com/yurayanaqi/edit?html,js,console,output

いろいろ:

* 認証の$http部分は偽物のFactoryにしていて、2秒待って返すだけです。
* `.success` `.error` スタイルの作り方が出てこなかったんで、promiseになってます。thenの第一引数がsuccessで、第二引数がerror。
* success, errorの引数が違います(statusやdataは response.status, response.data に。判定につかっているdata以外は気にしてません)。
* httpDummyのfailureTest とか errorTestをtrueにすると、エラーっぽい挙動とdataを返さない挙動になります。
* consoleにちょびちょびログ吐いてます。
* ChromeとIE11で確認しました。

---

## 追記

まず先に、`ng-sugmit`は `Html.BeginForm` で `ng_submit`として属性を追加してあげれば使えます。
以下のサンプルにもボタンを追加して、`ng-submit`の動作を見ています。

Visual Studio 2013 pro, ASP.NET MVC 5.2.2, Chrome 45, AngularJS 1.3.0 [公式から]( https://code.angularjs.org/1.3.0/ )

ASP.NET Webアプリケーション - MVC のみチェック

で、以下の様なソースです。
ng_submit以外は JSBinの時と同じです。 2秒待ってsuccessの処理を行います。

jsBinに挙げたやつでは、関数名を`submitForm`に変えていたので、もしそっちからスクリプトだけコピペしてたら上手くいかないです。こっちに書いたのは提示ソースにそろえてるはずですが。


* Views/Test/Index.cshtml

```html
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
<div ng-app="app" ng-controller="MainCtrl as app">
    @ViewBag.Version

    @using (Html.BeginForm( "Main", "Test", null,
        FormMethod.Post, new {ng_submit = "angularSubmit($event)"})){
        <table>
            <tr>
                <th>ユーザーID</th>
                <td><input type="text" name="UserCode" ng-model="UserCode"/></td>
            </tr>
            <tr>
                <th>パスワード</th>
                <td><input type="text" name="UserPassword" ng-model="UserPassword"/></td>
            </tr>
            <tr>
                <td colspan="2" style="text-align: right;">
                    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)"/><br/>
                    {{loginResult}}<br/>
                    <input type="submit" value="ng-submit のテスト"/><br/>
                </td>
            </tr>
        </table>
    }
</div>
    <script src="~/Scripts/angular.js"></script>
    <script src="~/Scripts/app.js"></script>
</body>
</html>
```

* Scripts/app.js

```javascript
var app = angular.module('app', []);
app.constant('AUTH_API', 'http://example.com/auth');
app.controller('MainCtrl', function ($scope, AuthApiAlternate, AUTH_API) {

    $scope.DoAuthenticate = DoAuthenticate;
    $scope.angularSubmit = angularSubmit;
    $scope.loginResult = "angular is working";

    function DoAuthenticate(e) {
        e.preventDefault();

        var $http = AuthApiAlternate.httpDummy;
        $http({
            method: 'GET',
            url: AUTH_API
        }).then(function (response) {
            if (!response.data) {
                $scope.loginResult = "ログインに失敗しました";
            } else {
                $scope.loginResult = null;
                document.getElementsByTagName('form')[0].submit();
            }
        }, function (response) {
            console.log(response.status);
        });
        console.log('my dummy return results after 2 sec.');
        return false;
    }

    function angularSubmit() { // ng-submit用
        alert('ng-submit!');
    }
});

// $httpの代わり。jsbinの時と同じ。2 秒待って successになる。 failureTestやerrorTestをいじると挙動が変わる
app.factory('AuthApiAlternate', function ($q) {
    return { httpDummy: httpDummy };
    function httpDummy(opt) {
        var defer = $q.defer();
        var failureTest = false;
        var errorTest = false;
        console.log('url you specified :' + opt.url);
        setTimeout(function () {
            if (failureTest) {
                console.log('failure');
                defer.resolve({ status: 200 });
                return;
            }
            if (errorTest) {
                defer.reject({ status: 500, data: "something wrong happend" });
                return;
            }
            defer.resolve({ status: 200, data: 'You logged in.' });
            return;
        }, 2000);
        return defer.promise;
    }
});
```

* Controllers/TestController.cs

```cs
namespace InjectSubmit.Controllers{

    /// <summary> qait 9560 </summary>
    public class TestController : Controller{
        // GET: Test
        public ActionResult Index(){
            ViewBag.Version = typeof(Controller).Assembly.GetName().Version.ToString();
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public String Main(){
            return "Post Success :" + Request.Form["userCode"];
        }
   }
}
```

回答を投稿

javascript部分しか確認してません。
とりあえず現状からであれば、successの中でjavascriptでsubmitして、
ボタンのイベント自体はキャンセルしてしまうという手があると思います。

イベントオブジェクト($event)をng-clickに追加

    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)" /><br />

イベントハンドラの修正

    $scope.DoAuthenticate = function(e) {  // 引数追加
     e.preventDefault();                   // 追加

     $http({
      method : 'GET',
      url : "認証用のurl"
     }).success(function(data, status, headers, config) {
      if (!data) {
       $scope.loginResult = "ログインに失敗しました";
       return;   // 追加
      }
      document.getElementsByTagName('form')[0].submit(); // 追加:formは 1つしかないと仮定してます
     }).error(function(data, status, headers, config) {
      console.log(status);
     });

     return false; // 追加
    };

スクリプトからsubmitしているのでユーザーアクションとみなされないので例えば target="_blank"とかだとポップアップブロックに引っかかるなど、制限がかかる場合があります。

老婆心ながら、このスクリプトからもわかるように、api呼ばずにsubmitできてしまう(
javascript:document.getElementsByTagName('form')[0].submit(); とか)
ので、そのあたりは注意してください。

具体的なコードは考えてないですが、formのng-submitで拾った方が良さそうな気はしますが、それだとsubmitしようが無くなるんですかね?

ブラウザとangularjsのバージョンは書いておいてほしいところです。特にangularはバージョン間の差分がそれなりにあるので。

jsbinでのデモ (自分が確認するために書いたもの。説明が長いので試してみたいときだけどうぞ)

※ jsbin.comの他、ボタン押下後、最後に http://posttestserver.comに実際にPOSTしてます。
(ソース見るだけならPOSTは発生しません。)
※ 実行するときは(出力画面が別画面じゃないとリフレッシュされたのわからないので)OUTPUTペインの分離ボタン押してから実行してください

qait9560.png

https://jsbin.com/yurayanaqi/edit?html,js,console,output

いろいろ:

  • 認証の$http部分は偽物のFactoryにしていて、2秒待って返すだけです。
  • .success .error スタイルの作り方が出てこなかったんで、promiseになってます。thenの第一引数がsuccessで、第二引数がerror。
  • success, errorの引数が違います(statusやdataは response.status, response.data に。判定につかっているdata以外は気にしてません)。
  • httpDummyのfailureTest とか errorTestをtrueにすると、エラーっぽい挙動とdataを返さない挙動になります。
  • consoleにちょびちょびログ吐いてます。
  • ChromeとIE11で確認しました。
javascript部分しか確認してません。
とりあえず現状からであれば、successの中でjavascriptでsubmitして、
ボタンのイベント自体はキャンセルしてしまうという手があると思います。

イベントオブジェクト(`$event`)をng-clickに追加

```html
    <input type="submit" value="ログイン" name="LoginSubmit" ng-click="DoAuthenticate($event)" /><br />
```

イベントハンドラの修正

```javascript
    $scope.DoAuthenticate = function(e) {  // 引数追加
     e.preventDefault();                   // 追加
     
     $http({
      method : 'GET',
      url : "認証用のurl"
     }).success(function(data, status, headers, config) {
      if (!data) {
       $scope.loginResult = "ログインに失敗しました";
       return;   // 追加
      }
      document.getElementsByTagName('form')[0].submit(); // 追加:formは 1つしかないと仮定してます
     }).error(function(data, status, headers, config) {
      console.log(status);
     });

     return false; // 追加
    };
```

スクリプトからsubmitしているのでユーザーアクションとみなされないので例えば `target="_blank"`とかだとポップアップブロックに引っかかるなど、制限がかかる場合があります。

老婆心ながら、このスクリプトからもわかるように、api呼ばずにsubmitできてしまう( 
`javascript:document.getElementsByTagName('form')[0].submit();` とか)
ので、そのあたりは注意してください。

具体的なコードは考えてないですが、formのng-submitで拾った方が良さそうな気はしますが、それだとsubmitしようが無くなるんですかね?

ブラウザとangularjsのバージョンは書いておいてほしいところです。特にangularはバージョン間の差分がそれなりにあるので。


jsbinでのデモ (自分が確認するために書いたもの。説明が長いので試してみたいときだけどうぞ)

※ jsbin.comの他、ボタン押下後、最後に `http://posttestserver.com`に実際にPOSTしてます。
(ソース見るだけならPOSTは発生しません。)
※ 実行するときは(出力画面が別画面じゃないとリフレッシュされたのわからないので)OUTPUTペインの分離ボタン押してから実行してください

![qait9560.png](https://qa-atmarkit-image.s3.amazonaws.com/uploads/attached_image/image/121/qait9560.png)


https://jsbin.com/yurayanaqi/edit?html,js,console,output

いろいろ:

* 認証の$http部分は偽物のFactoryにしていて、2秒待って返すだけです。
* `.success` `.error` スタイルの作り方が出てこなかったんで、promiseになってます。thenの第一引数がsuccessで、第二引数がerror。
* success, errorの引数が違います(statusやdataは response.status, response.data に。判定につかっているdata以外は気にしてません)。
* httpDummyのfailureTest とか errorTestをtrueにすると、エラーっぽい挙動とdataを返さない挙動になります。
* consoleにちょびちょびログ吐いてます。
* ChromeとIE11で確認しました。