I have a partialview where it's possible to change a Connection String. When submitting an Edit action is called. From here I want to either return and re-open the partial view if I want the user to have a second go. If everything went well (or crashing) I want to call my JavaScript function Logout, that logs the user out and redirect to some startpage.
Both solutions works, just not together. I'm clearly missing some best practice, what should I do?
Partial View: EditSetting
@model WebConsole.ViewModels.Setting.SettingViewModel
@using (Ajax.BeginForm("Edit", "Setting", new AjaxOptions { UpdateTargetId = "div" }, new { id = "editform" }))
{
<fieldset>
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new {@class = "text-danger"})
<div class="form-group">
@Html.LabelFor(model => model.User, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.User, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.User, "", new {@class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
<input type="password" name="Password" id="Password" value=""/>
@Html.ValidationMessageFor(model => model.Password, "", new {@class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DataSource, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.DataSource, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.DataSource, "", new {@class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.InitialCatalog, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.InitialCatalog, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.InitialCatalog, "", new {@class = "text-danger"})
</div>
</div>
</div>
</fieldset>
}
JavaScript: Submit
$('form').submit(function () {
var $self = $(this);
if ($(this).valid()) {
// Change Connection String
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (message) {
// Use Partial View
//$('#myModal .modal-body').html(message);
// Conn Str is now changed. Log out and redirect
logOut($self, message);
},
error: function (message) {
logOut($self, message);
}
});
}
return false;
});
Action: Edit
[HttpPost]
public ActionResult Edit(SettingViewModel model)
{
// Validate inputs
if (!ModelState.IsValid)
{
ModelState.AddModelError("", @"Not all inputs are valid.");
return PartialView("EditSetting", model);
}
var sql = new DAL.SQL(DAL.SQL.GenerateConnectionString(model.DataSource, model.InitialCatalog, model.User, SecurePassword(model.Password)));
// Validate Connection String
if (!sql.Open())
{
ModelState.AddModelError("", @"Error. Unable to open connection to Database.");
return PartialView("EditSetting", model);
}
// Validate a transaction
if (!sql.IsRunningTransact())
{
ModelState.AddModelError("", @"Error. Unable to connect to Database Server.");
return PartialView("EditSetting", model);
}
// Save Connection String
BuildAndEncryptConnString(model);
return Content("The Connection String is changed. Log in again to continue.");
}
Using the extension method RenderToString and basead on cacois answer, you can create your action like this:
public ActionResult Edit(SettingViewModel model)
{
// "Ifs" to return only partials
if (ModelState.IsValid)
{
return PartialView("EditSetting", model);
}
...
// Returning a Json with status (success, error, etc), message, and the content of
// your ajax, in your case will be a PartialView in string
return Json(new {
Status = 1,
Message = "error message",
AjaxReturn = PartialView("EditSetting", model).RenderToString()});
}
Ps. I suggest you to create a model to define the Ajax return, with Status, Message and AjaxReturn. With that, your ajax requests will always return the same object type. For the Status property you can create a Enum.
Your ajax request, will be like this:
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (data) {
if(data.Message == undefined) {
// Use data like a partial
} else {
// Use data.Message for the message and data.AjaxReturn for the partial
}
},
error: function (message) {
logOut($self, message);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With