1

У меня есть частичное представление, где можно изменить строку соединения. При отправке действия Edit вызывается. Отсюда я хочу либо вернуться, либо снова открыть частичный вид, если я хочу, чтобы у пользователя был второй ход. Если все пойдет хорошо (или сбой), я хочу вызвать свою функцию JavaScript Logout, которая регистрирует пользователя и перенаправляет на какую-то стартовую страницу.Возвращение как частичного просмотра, так и сообщения

Оба решения работают, только не вместе. Мне явно не хватает лучшей практики, что мне делать?

Частичный вид: 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: Отправить

$('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; 
}); 

Действие: Редактировать

[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."); 
} 
+1

Посмотрите на этот ответ: http://stackoverflow.com/a/5359628/5071902 –

+0

@ RenanAraújo Мне не нужно отображать представление в виде строки.Мне нужно знать клиентскую сторону, если мой результат (сообщение) возвращается из действия, является частичным представлением, которое мне нужно повторно отобразить, или это сообщение, которое мне нужно запросить у пользователя, прежде чем я выхожу из системы и перенаправляю пользователя его на стартовую страницу. :) – radbyx

+0

@ RenanAraújo Скажите, пожалуйста, если я ошибаюсь, я просто говорю это, пока я это вижу. Возможно, я пока этого не понимаю. – radbyx

ответ

4

Используя метод расширения RenderToString и basead на cacois answer, вы можете создать свои действия так:

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()}); 
} 

Пс. Я предлагаю вам создать модель для определения возврата Ajax, с Status, Message и AjaxReturn. При этом ваши запросы ajax всегда будут возвращать один и тот же тип объекта. Для свойства Status вы можете создать Enum.

Ваш Аякса запрос, будет выглядеть следующим образом:

$.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); 
    } 
}); 
+1

Вместо "AjaxReturn = RenderViewToString (PartialView (" EditSetting ", model))};" Вы имели в виду: «AjaxReturn = RenderViewToString (PartialView (« EditSetting », model) .ViewName, model)}); – radbyx

+0

Ваш код работает с редактированием, которое я сделал, за исключением случаев, когда пользователь неправильно ошибался в первой попытке. Может быть, это мое редактирование, где я использовал «.ViewName», или это может быть «$ self», которое больше не запоминается в javascript Closure, я не знаю? – radbyx

+1

Вы правы, чтобы использовать этот метод, вам нужно использовать его так, как вы. Я изменил метод на «RenderToString», созданный Тедом Нюбергом, я думаю, теперь он более чист. –

0

Вы можете вернуть Патиальный просмотр и Intialize ViewBag и назначить ему сообщение, а затем в представлении проверить, есть ли значение и показать его, если true.

Контроллер:

[HttpPost] 
public ActionResult Edit(SettingViewModel model) 
{ 
    // Put the ViewBag where ever you want 
    ViewBag.ErrorMsg =" Error"; 
    return PartialView("EditSetting", model); 
} 

Вид:

@if(ViewBag.ErrorMsg !=null) 
{ 
    <div>@ViewBag.ErrorMsg</div> 
} 

Я надеюсь, что помог.

+0

Да, я подумал об этом, просто используя модель. Я подумал, что это взломать, но может быть, все будет хорошо, я попробую - спасибо :) – radbyx

+0

@ Darin Dimitrov Бог MVC, НЕ рекомендую ViewBag: http://stackoverflow.com/questions/6858723/lifetime -of-viewbag-elements-in-asp-net-mvc3 – radbyx

+0

Пожалуйста, прочтите это. https://jamietech.com/2015/10/14/mvc-view-models-or-viewdata/ –

0

Добавить обработку ошибок в вашей ViewModel:

bool hasErrors; 
string errorMessage; 

В контроллере, если проверка данных в порядке, просто вернуть PartialView или return RedirectToAction("Index");. Если нет, установите hasErros = true; и обычай errorMessage.

В представлении, поместите блок кто-то об ошибке, в котором пользователь будет видеть его:

@if (Model.hasErrors) 
{ 
    <div>Model.errorMessage</div> 
} 

Кстати, вы можете сделать проверку данных внутри конструктора ViewModel.

Смежные вопросы