Визуализация частичного представления с помощью Ajax Unobtrusive

У меня есть следующий вид и частичный вид. В методе действия index мне нужно, чтобы Create отображался как частичное представление. Основываясь на ответе на этот вопрос, я попытался использовать вспомогательные методы Ajax (я нахожу, что AJAX и JS так трудно понять).

@model IEnumerable<TEDALS_Ver01.Models.UserRight>

@{
ViewBag.Title = "Index";
}
<table class="table">
<tr>
    <th>
        @Html.DisplayNameFor(model => model.UserName)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.UserCode)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.IsReader)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.IsEditor)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.IsExporter)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.IsAdmin)
    </th>
    <th></th>
</tr>
@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.UserName)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.UserCode)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IsReader)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IsEditor)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IsExporter)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IsAdmin)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.UserRightID }) |
        @Html.ActionLink("Details", "Details", new { id=item.UserRightID }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.UserRightID })
    </td>
</tr>
}

</table>
<p>
@Ajax.ActionLink("Creates", "Creates", "UserRights", new { area = "Creates" }, new AjaxOptions { UpdateTargetId="Creates"})
</p>
<div id="Creates">
@Html.RenderPartial("_Creates",Model);
</div>

Частичный вид

  @model TEDALS_Ver01.Models.UserRight
  @Scripts.Render("~/bundles/jqueryval")
  @using (Ajax.BeginForm("Creates", "Creates", new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace }))
 {
 @Html.AntiForgeryToken()
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })

    @Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } })
    @Html.ValidationMessageFor(model => model.UserName, "", new { @class = "text-danger" })

    @Html.LabelFor(model => model.UserCode, htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.UserCode, new { htmlAttributes = new { @class = "form-control" } })
    @Html.ValidationMessageFor(model => model.UserCode, "", new { @class = "text-danger" })

    @Html.LabelFor(model => model.IsReader, htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.IsReader)
    @Html.ValidationMessageFor(model => model.IsReader, "", new { @class = "text-danger" })

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
   </div>
  }

<div>
@Html.ActionLink("Back to List", "Index")
</div>

Я получаю ошибку при выполнении:

 Compilation Error
 Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

 Compiler Error Message: CS1502: The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments

Любая помощь будет оценена. Я попытался изменить аргументы для RenderPartial во многих отношениях и не увенчался успехом.

Комментарии

Я добавил все сценарии в свой макет.

ошибка

 An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code

 Additional information: The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[TEDALS_Ver01.Models.UserRight]', but this dictionary requires a model item of type 'TEDALS_Ver01.Models.UserRight'.

РЕДАКТИРОВАТЬ на основе вкладов Грега

Главный вид

   @model IEnumerable<TEDALS_Ver01.Models.UserRight>
   @using TEDALS_Ver01.Models
   <p>
   @Html.ActionLink("Create New", "Create")
   </p>
   <table class="table">
   <tr>
   <th>
        @Html.DisplayNameFor(model => model.UserName)
   </th>
   <th>
        @Html.DisplayNameFor(model => model.UserCode)
   </th>
   <th>
        @Html.DisplayNameFor(model => model.IsReader)
   </th>
   <th>
        @Html.DisplayNameFor(model => model.IsEditor)
   </th>
   <th>
        @Html.DisplayNameFor(model => model.IsExporter)
   </th>
   <th>
        @Html.DisplayNameFor(model => model.IsAdmin)
   </th>
   <th></th>
  </tr>
  @foreach (var item in Model) {
  <tr>
    <td>
        @Html.DisplayFor(modelItem => item.UserName)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.UserCode)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IsReader)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IsEditor)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IsExporter)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IsAdmin)
    </td>

    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.UserRightID }) |
        @Html.ActionLink("Details", "Details", new { id=item.UserRightID }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.UserRightID })
    </td>
   </tr>
   }

   </table>

   <input type="button" value="Create" id="Creates" />
   <div id="Creates">
   @{  
   Html.Partial("_Creates",new TEDALS_Ver01.Models.UserRight());
   }
   </div>

Я понимаю, что некоторые скрипты, которые должны быть использованы, чтобы сделать это правильно, отсутствуют. Но я не знаю, где сценарии должны быть добавлены. Я сталкивался с той же проблемой раньше и не смог решить, исключил часть, которая использовала скрипты.

Моя кнопка Создать ничего не делает. В консоли браузера я получаю сообщение об ошибке Элемент не найден.

2 ответа

Решение

Сообщение об ошибке, которое вы получаете состояния

Элемент модели, переданный в словарь, имеет тип 'System.Collections.Generic.Перечислите1[TEDALS_Ver01.Models.UserRight], но для этого словаря требуется элемент модели типа TEDALS_Ver01.Models.UserRight'

Это говорит о том, что созданный вами вид обрабатывает только один UserRight но ты дал ему List<UserRight>, Ошибка, кажется, происходит здесь, в вашем главном представлении:

<div id="Creates">
@Html.RenderPartial("_Creates",Model);
</div>

Текущая модель является коллекцией, поэтому рендеринг _Creates.cshtml с этим объектом не удастся.

Обычно, способ обойти это, чтобы обойти модель

 @foreach(var modelItem in Model) {
  <div id="Creates">
    @Html.RenderPartial("_Creates", modelItem);
  </div>
 }

Но в этом случае я не думаю, что это то, что вы хотите вообще.

Прямо сейчас, если вы удалили вызов RenderPartial, он, скорее всего, скомпилируется, а когда вы нажмете ссылку "Создание", он отправит GET для действия "Создание", которое будет отображать любой вид, к которому он подключен (что звучит как фрагмент, который вы опубликовали в своем вопросе).

Затем пользователь заполняет форму в частичном и отправляет его в Creates и div#Creates затем снова заменяется любым видом, полученным из действия post.

Похоже, что вы действительно хотите, чтобы визуализировать форму, а затем заменить форму, когда она размещена. Для этого сначала нужно удалить @Ajax.ActionLink так как ты не хочешь div#Creates должен быть заменен ссылкой при загрузке страницы. Вы находитесь на правильном пути рендеринга этого частичного, но проблема в том, что вы дали ему объект.

Вы можете попробовать дать ему пустое UserRight

<div id="Creates">
  @Html.Partial("_Creates", new TEDALS_Ver01.Models.UserRight());
</div>

Но если это не сработает, вам нужно создать ViewModel для этого представления, которое содержит список пользовательских прав, которые вы хотите отобразить, а также шаблон UserRight, который может использовать ваша форма.


В качестве примечания: поскольку у меня недостаточно очков, чтобы комментировать ответ @dylan-slabbinck, вы хотите использовать @Html.Partial, а не @Html.RenderPartial.

Используйте это так @{ Html.RenderPartial("_Creates", Model);}

Html.Render... помощники возвращаются voidэто, вероятно, причина, по которой вы получаете ошибку

Другие вопросы по тегам