2017-01-22 14 views
0

私はそれが同じクライアントかどうかを特定する必要があるので、コントローラのアクションメソッドで、後で表示するために送信するビューモデルにidを入れます。ユーザーがブラウザで何らかのコンテンツを入力して送信すると、ユーザーの入力と、コントローラが表示するために送信したIDを含むビューモデルをコントローラに戻す必要があります。しかし、この場合、デバッグするとき、私はIDを持っていないコントローラに戻って送られたビューモデルを発見しました。私はどんなことを忘れましたか?asp.net:コントローラとビューの間で同じデータを渡す方法は?

私はおそらく、ビューはユーザーの入力を読み込むための新しいビューモデルを作成すると思いますが、IDは古いビューモデルにあります。ここで

// GET: /Account/Register 
      var registerViewModel = new RegisterViewModel() {OpenId = wechatUserAccessToken.openid}; 
      return View(registerViewModel); 

POST:以下

@model MicroCommunity.Models.RegisterViewModel 
@{ 
    ViewBag.Title = "Register"; 
} 

<h2>@ViewBag.Title.</h2> 

@using (Html.BeginForm("Register", "Account", FormMethod.Post, new {@class = "form-horizontal", role = "form"})) 
{ 
    @Html.AntiForgeryToken() 
    <h4>Create a new account.</h4> 
    <hr/> 
    @Html.ValidationSummary("", new {@class = "text-danger"}) 



    <div class="form-group"> 
     @Html.LabelFor(m => m.Name, new {@class = "col-md-2 control-label"}) 
     <div class="col-md-10"> 
      @Html.TextBoxFor(m => m.Name, new {@class = "form-control"}) 
     </div> 
    </div> 
    <div class="form-group"> 
     @Html.LabelFor(m => m.Department, new {@class = "col-md-2 control-label"}) 
     <div class="col-md-10"> 
      @Html.TextBoxFor(m => m.Department, new {@class = "form-control"}) 
     </div> 
    </div> 
    <div class="form-group"> 
     @Html.LabelFor(m => m.EmployeeCardURL, new {@class = "col-md-2 control-label"}) 
     <div class="col-md-10"> 
      @Html.TextBoxFor(m => m.EmployeeCardURL, new {@class = "form-control"}) 
     </div> 
    </div> 
    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" class="btn btn-default" value="Register"/> 
     </div> 
    </div> 
} 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

は、GETメソッドのコードの一部であるビューでOpenIdプロパティには、対応するinputフィールドがありません

 // POST: /Account/Register 
     [HttpPost] 
     [AllowAnonymous] 
     [ValidateAntiForgeryToken] 
     public async Task<ActionResult> Register(RegisterViewModel model) 
     { 
      if (ModelState.IsValid) 
      { 
       var user = new ApplicationUser 
       { 
        Openid =model.OpenId, 
        UserName = model.OpenId, 
        EmployeeCardURL = model.EmployeeCardURL, 
        Department = new Department() {Name = model.Department}, 
        Name = model.Name 
       }; 
       try 
       { 
        var result = await UserManager.CreateAsync(user, model.OpenId); 
        if (result.Succeeded) 
        { 
         await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 

         // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 
         // Send an email with this link 
         // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); 
         // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); 
         // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>"); 

         return RedirectToAction("Index", "Home"); 
        } 
        AddErrors(result); 
       } 
       catch (DbEntityValidationException e) 
       { 
        foreach (var eve in e.EntityValidationErrors) 
        { 
         Console.WriteLine(
          "Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", 
          eve.Entry.Entity.GetType().Name, eve.Entry.State); 
         foreach (var ve in eve.ValidationErrors) 
         { 
          Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"", 
           ve.PropertyName, ve.ErrorMessage); 
         } 
        } 
        throw; 
       } 
      } 

      // If we got this far, something failed, redisplay form 
      return View(model); 
     } 
+1

ビューおよびアクションメソッドから関連コードを転記してください –

+0

オブジェクトの同じインスタンスを使用していることを確認してください。 – jdweng

+0

htmlファイルを共有してください –

答えて

2

、あなたので、何とかそれがあなたのPOSTアクションに自動的に送信されることを期待できません。だから、どこか中にあなたHtml.BeginForm隠しフィールドとしてそれを含めて検討することがあります。

@Html.HiddenFor(x => x.OpenId) 

ASP.NET MVCステートレスです。これは、ビューをレンダリングするときに1つのビューモデルを送信することを意味しますが、別のコントローラアクションにポストバックするときに、同じビューモデルを取得するとは限りません。

さて、これは言われて、あなたは、このアプローチを使用することにより、誰もがあなたのPOSTのコントローラのアクションと偽物彼が望んでどのような値でOpenIdプロパティにリクエストを送ることができることに注意する必要があります。この値が間に改ざんされていないことを確認したい場合は、POSTアクション内でGETアクション(通常はデータベースまたはキャッシングレイヤー)で行ったのと同じ場所から取得することを検討することができます。あなたのPOSTアクションでそう

string openId = wechatUserAccessToken.openid; 

それはこのwechatUserAccessTokenインスタンスが何であるかは不明だが、それはあなたのPOSTアクションで使用できない場合、あなたはあなたのサーバー上のどこかにこのopenid値を格納する検討するかもしれない(中すべてのリクエストに非表示フィールドとして含める必要はなく、現在ログインしているユーザーセッションに関連付ける必要があります。これにより、サーバー上で常に値が使用可能で改ざんされないことが保証されます。

+0

「OpenId」はユーザを識別するために使用されるため、「OpenId」は偽造される可能性があることを指摘していただきありがとうございます。クライアントが 'OpenId'をサーバに送信しなかった場合、サーバはそれが誰であるかを知ることができません。 – guo

+0

いいえ、それは当てはまりません。 'GET'アクションでこの値を完全に細かく取得しました。したがって、単にサーバーのどこかに格納し、現在のユーザーセッションに関連付けることができます。 ASP.NET FOrms認証についての詳細は、ユーザーセッションについて学ぶことができます。 –

関連する問題