2016-09-27 37 views
0

好的,這是我的第一個問題,所以我會盡量清楚,不要重複別人以前問過的。在發佈之前,我確實嘗試在論壇上搜索,但我沒有發現任何能夠幫助我解決問題的東西。如果我錯過了一個本來適合的答案,請輕輕地將這個問題重複一次。asp.net核心用戶通知後形式發帖

所以我的目標是在發佈表單的部分視圖後發送通知給用戶,告訴他它是否工作或者後端是否有問題。我也不希望重新加載整個視圖來顯示通知。

我的問題是什麼是最好的方式發送通知從後端到UI而不刷新整個視圖。

這是迄今爲止我嘗試過,爲什麼它沒有工作:

  1. 第一次嘗試將數據添加到的ViewData字典並把它傳遞給視圖。它的工作原理,但再次加載整個頁面,這是不受歡迎的。

  2. 當我看到通過搜索,這是一個很好的做法,重定向到一個返回視圖之前GET要求,我創建了一個重定向到一個成功的方法,那麼這將顯示的ViewData字典,而是我發現,它不起作用,因爲重定向不允許我通過viewdata傳遞任何東西。

  3. 後來我發現,我可能會使用TempData的,因爲它的生活通過重定向而不是的ViewDataViewBag。這個解決方案的問題在於,存在一些安全問題,並且我無法在客戶端運行我的JavaScript,除了警報,這對用戶來說不是很有吸引力。

  4. 我做的最後一次嘗試是使用Ajax請求,以便不會刷新頁面,然後我只能在服務器響應後才發送通知給用戶。這個解決方案的問題是,我似乎無法獲得表單數據到後端,它總是填充空值。值得注意的是,我試圖在ContactViewModel之前添加[FromBody]屬性,因爲我在其他帖子中看到它是它沒有正確綁定的原因,但它對我無效。 這裏是我到目前爲止的代碼:

a。對於控制器:

[HttpPost] 
[AjaxOnly] 
public async Task<IActionResult>SendContactRequest(ContactViewModel model) 
{ 

    if (ModelState.IsValid) 
    { 
     string recipientEmailAddresses = [email protected]; 

      string subject = "Website customer request from " + model.firstName + " " + model.lastName; 
      string message = ""; 
      if (model.jobTitle != null) 
      { 
       message += "Job title: " + model.jobTitle; 
      } 
      message += "Request or comment: " + model.requestMsg; 

      // Only actually send the message if we are in production/staging or other, anything else than development 
      if (!_env.IsDevelopment()) 
      { 
       await _emailSender.SendEmailAsync(model.contactEmail, $"{model.firstName} {model.lastName}", recipientEmailAddresses, subject, message); //using interpolated string here 
      } 

      // Sending confirmation via response.writeAsync 
      await Response.WriteAsync("success"); 
     } 
     else 
     { 
      await Response.WriteAsync("the message could not be sent as model is not valid"); 
     } 

     // this method redirects to the good section on page, but cannot pass the model along with it... 
     return Redirect("Index#contact"); 
    } 

b。對於客戶端:

<form id="contactForm" asp-controller="Home" asp-action="SendContactRequest"> 
    <div class="form-group"> 
     @*<label asp-for="firstName">First Name</label>*@ 
     <input asp-for="firstName" class="form-control" placeholder="First name" /> 
     <span asp-validation-for="firstName" class="text-warning"></span> 
    </div> 
    <div class="form-group"> 
     @*<label asp-for="lastName">Last Name</label>*@ 
     <input asp-for="lastName" class="form-control" placeholder="Last name" /> 
     <span asp-validation-for="lastName" class="text-warning"></span> 
    </div> 
    <div class="form-group"> 
     @*<label asp-for="contactEmail">Contact Email</label>*@ 
     <input asp-for="contactEmail" class="form-control" placeholder="Full email address" /> 
     <span asp-validation-for="contactEmail" class="text-warning"></span> 
     <small id="email" class="form-text text-muted">We'll never share your email with anyone else.</small> 
    </div> 
    <div class="form-group"> 
     @*<label asp-for="jobTitle">Job title</label>*@ 
     <input asp-for="jobTitle" class="form-control" placeholder="Job title (optional)" /> 
     <span asp-validation-for="jobTitle" class="text-warning"></span> 
    </div> 
    <div class="form-group"> 
     @*<label asp-for="jobTitle">Job title</label>*@ 
     <textarea asp-for="requestMsg" class="form-control" placeholder="Request or comment" rows="8"></textarea> 
     <span asp-validation-for="requestMsg" class="text-warning"></span> 
    </div> 

    <button type="submit" class="btn btn-primary">Submit</button> 
</form> 

c。最後對於腳本部分(Ajax調用):

// Attach a submit handler to the form 
    $("#contactForm").submit(function (event) { 

     // Stop form from submitting normally 
     event.preventDefault(); 

     var formdata = new FormData(document.querySelector('#contactForm')[0]); 

     // Send the data using ajax 
     $.ajax({ 
      type: "POST", 
      url: $form.attr("action"), 
      data: formdata, 
      processData: false, 
      contentType: false, 
      success: function (response) { 
       if (response.includes("success")) { 
        alert(response); 
        document.getElementById("contactRequestForm").reset(); 
       } 
      }, 
      error: function() { 
       alert("Mail not sent, please try again later \n If this error persists, please contact us directly via email @ [email protected]"); 
      } 
     }); 
    }); 

回答

2

方法4是我會推薦的(Ajax)。你的代碼中有一個小問題,它發佈了表單數據,這就是爲什麼它沒有綁定到你的模型。

// Attach a submit handler to the form 
$("#contactForm").submit(function (event) { 

    // Stop form from submitting normally 
    event.preventDefault(); 

    // this won't work - take out the indexer 
    // var formdata = new FormData(document.querySelector('#contactForm')[0]); 

    // this should work 
    var formdata = new FormData(document.querySelector('#contactForm')); 


    // Send the data using ajax 
    $.ajax({ 
     type: "POST", 
     url: $form.attr("action"), 
     data: formdata, 
     processData: false, 
     contentType: false, 
     success: function (response) { 
      if (response.includes("success")) { 
       alert(response); 
       document.getElementById("contactRequestForm").reset(); 
      } 
     }, 
     error: function() { 
      alert("Mail not sent, please try again later \n If this error persists, please contact us directly via email @ [email protected]"); 
     } 
    }); 
}); 

但是,您的控制器代碼不會做你想做的。你真的可能希望它返回某種類型的json類型的響應與任何模型錯誤等,但是,這段代碼應該讓你到它正確綁定到模型的點,然後你可以擺弄你的控制器方法來返回一些東西更合理的(不是一個redirect

+0

或使用jquery的表單數據:var formdata = new FormData($('#contactForm')[0]);' - 也許這是你的原意。 –

+0

感謝您的輸入。對於控制器,它實際上做我想做的事情,因爲在發佈請求之前,在客戶端完成對模型錯誤的驗證。 至於索引,我不知道爲什麼,但如果我按照建議移除它,在調試控制檯(Chrome開發工具)中出現以下錯誤:「參數不可選」 – Os1r1s110

+0

錯誤發生在哪裏?當我在本地進行測試時,我確實必須將'$ form.attr'更改爲'$(「#contactForm」)。attr',但我不確定是否使用了我沒有的插件,所以我離開了這在我的文章中保持不變。也許就是這樣?或者,在我的第一條評論中嘗試jQuery語法。 –