问题
In an MVC5 project, I open a modal dialog and in case there is an exception, I want to open this dialog and display a message on a div in this dialog. As far as I see, I should follow the approach as rendering partialview into a string, but most of the examples does not work in MVC5 as on Return Partial View and JSON from ASP.NET MVC Action. Is there any similar or better approach working for MVC5?
回答1:
You can do the following
Solution 1 ( using partial views)
[HttpPost]
public ActionResult YourAction(YourModel model)
{
if(model!=null && ModelState.IsValid)
{
// do your staff here
Response.StatusCode = 200; // OK
return PartialView("ActionCompleted");
}
else
{
Response.StatusCode = 400; // bad request
// ModelState.ToErrors() : is an extension method that convert
// the model state errors to dictionary
return PartialView("_Error",ModelState.ToErrors());
}
}
Your partial view should look like:
<div id="detailId">
<!-- Your partial details goes here -->
....
<button type="submit" form="" value="Submit">Submit</button>
</div>
your script
<script>
$(document).ready(function(){
$('#formId').off('submit').on('submit', function(e){
e.preventDefault();
e.stopPropagation();
var form = $('#formId');
$.ajax({
url: form.attr('action'),
data: form.serialize(),
method: 'post',
success : function(result){
$('#detailId').replaceWith(result);
// another option you can close the modal and refresh your data.
},
error: function(data, status, err){
if(data.status == 400){
$('#detailId').replaceWith(data.responseText);
}
}
});
});
});
</script>
Solution 2 ( using Json)
in your action
[HttpPost]
public ActionResult YourAction(YourModel model)
{
if(model!=null && ModelState.IsValid)
{
// do your staff here
return Json(new {status = 200,
//...any data goes here... for example url to redirect
url=Url.Content("YourRedirectAction","Controller")},
}
else
{
return Json( new {status= 400,errors = ModelState.ToErrors()});
}
}
and your script should look like
<script>
$(document).ready(function(){
$('#formId').off('submit').on('submit', function(e){
e.preventDefault();
e.stopPropagation();
var form = $('#formId');
$.ajax({
url: form.attr('action'),
data: form.serialize(),
method: 'post',
success : function(result){
if(result.status==200) { // OK
// you might load another action or to redirect
// this conditions can be passed by the Json object
}
else{ // 400 bad request
// you can use the following toastr based on your comment
// http://codeseven.github.io/toastr/demo.html
var ul = $('<ul>')
for(var error in result.errors)
{
ul.append('<li><b>' + error.Key + '</b>:' + error.Value + '</li>;
}
toastr["warning"](ul[0].outerHTML);
}
}
});
});
});
</script>
Finally, if you want the extension ModelState.ToErrors()
public static IEnumerable ToErrors(this ModelStateDictionary modelState)
{
if (!modelState.IsValid)
{
return modelState.ToDictionary(kvp => kvp.Key,
kvp => kvp.Value.Errors
.Select(e => e.ErrorMessage).First())
.Where(m => m.Value.Count() > 0);
}
return null;
}
hope this will help you
回答2:
This is a valid example, i have used this technique many times. If it is a simple get call than i would suggest make a partial view of data you want to show and call it via jquery with code below.
$( "#result" ).load("@Url.Action("Account","HelloPartial")");
this will load the partial view its self in the popup. you won't have to convert it to strings.
来源:https://stackoverflow.com/questions/39625405/returning-partialview-json-from-mvc-5-controller