2016-09-27 40 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语法。 –