Диалоговое окно Jquery и частичное представление с помощью IValidatableObject mvc3

Я использую диалоговое окно jquery, чтобы показать детали моего представления для добавления и редактирования задачи.

Я смог показать форму, и на кнопке обновления первый уровень проверки работает нормально, то есть [Required] и [RegularExpression(...)], но он не работает на уровне проверки модели (IValidatableObject), модель возвращает ошибки, но форма не показывая их.

вот jQuery, который я использую

контроллер

 [HttpPost]
        public ActionResult _Degree(TDegree degree)
        {
            if (ModelState.IsValid)
            {
                if (degree.Degree == 0)
                {
                    db.TDegrees.Add(degree);
                    db.SaveChanges();
                }
                else
                {
                    TryUpdateModel<TDegree>(degree);
                }
                return RedirectToAction("Index", "Profile");
            }
            // what should i return here to stay on the dialog form + returning the errors? i tried this way to show the errors but the errors not shown as html but string
            return Content(ShowAllErrors());
        }
        private String ShowAllErrors()
        {
            StringBuilder sb = new StringBuilder();
            TagBuilder ul = new TagBuilder("ul");
            foreach (var e in ModelState.Values.Where(t => t.Errors.Count > 0))
            {
                foreach (var d in e.Errors)
                {
                    TagBuilder li = new TagBuilder("li");
                    li.MergeAttribute("class", "field-validation-error");
                    li.SetInnerText(d.ErrorMessage);
                    sb.Append(li.ToString());
                }
            }
            ul.SetInnerText(sb.ToString());
            return ul.ToString();
        }

модель

 public partial class TDegree : IValidatableObject
    {
        // Primitive properties

        public long Degree { get; set; }
        public int Country { get; set; }
        public long Applicant { get; set; }
        [DisplayName("Degree Type")]
        public short DegreeType { get; set; }
        [Required]
        public string Major { get; set; }
        [Required]
        public string Institution { get; set; }
        [DisplayName("Completion Year")]
        public short CompletionYear { get; set; }
        [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Email is not valid")]
        public string Email { get; set; }
        [DataType(DataType.PhoneNumber)]
        public string Phone { get; set; }
        public bool IsEducation { get; set; }

        // Navigation properties

        public virtual TApplicant TApplicant { get; set; }
        public virtual TCountry TCountry { get; set; }
        public virtual TDegreeType TDegreeType { get; set; }

        // this method is running after the attributes validations and its returning the errors correctly but they are not shown on the form!!
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (DegreeType == 0)
                yield return new ValidationResult("Degree Type is required", new string[] { "DegreeType" });
            if (CompletionYear < 1950 || CompletionYear > DateTime.Today.Year)
                yield return new ValidationResult("Completion Year is out of range!", new string[] { "CompletionYear" });

        }
    }

представление индекса

@Html.ImageLink("_Degree", "Profile", new { id = 0 }, @Url.Content("~/Content/images/add.png"), "Add", new { @class = "addLink" }, null)
<table>
    <tr>
        <th>
            Country
        </th>
        <th>
            Type
        </th>
        <th>
            Major
        </th>
        <th>
            Institution
        </th>
        <th>
            Year
        </th>
        <th>
            Email
        </th>
        <th>
            Phone
        </th>
        <th>
        </th>
    </tr>
    @foreach (var item in Model)
    {
        <tr class="row">
            <td>
                @Html.DisplayFor(modelItem => item.TCountry.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TDegreeType.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Major)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Institution)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CompletionYear)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Email)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Phone)
            </td>
            <td>
                @Html.ImageLink("_Degree", "Profile", new { id = item.Degree }, @Url.Content("~/Content/images/select.png"), "Edit", new { @class = "editLink" }, null)
            </td>
        </tr>
    }
</table>
<div id="updateDialog" title="Degree Details">
</div>
<script type="text/javascript">
    var linkObj;
    $(function () {
        $('#updateDialog').dialog({
            autoOpen: false,
            width: 590,
            resizable: false,
            modal: true,
            buttons: {
                "Update": function () {
                    $("#update-message").html('');
                    $("#updateDegreeForm").validate();
                    $("#updateDegreeForm").submit();
                },
                "Cancel": function () {
                    $(this).dialog("close");
                }
            }
        });

        $(".editLink,.addLink").click(function () {
            linkObj = $(this);

            var dialogDiv = $('#updateDialog');
            var viewUrl = linkObj.attr('href');
            $.get(viewUrl, function (data) {
                dialogDiv.html(data);
                var $form = $("#updateDegreeForm");
                $form.unbind();
                $form.data("validator", null);
                $.validator.unobtrusive.parse(document);
                $form.validate($form.data("unobtrusiveValidation").options);
                dialogDiv.dialog('open');
            });
            return false;
        });

    });


    function updateSuccess() {
        if ($("#update-message").html() == "False") {
            $("#update-message").css('display', 'block');
            // here it working fine if the model attributes fired the errors
        }
        else {
             // if the model attributes validations was correct and the model validation returned errors, this block will be executed
             // i need here to show the errors of the model, and if there was no errors i will close the dialog
        }
    }

</script>

просмотр деталей (частичный просмотр)

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Ajax.BeginForm("_Degree", "Profile", null,
    new AjaxOptions
    {
        UpdateTargetId = "update-message",
        InsertionMode = InsertionMode.Replace,
        HttpMethod = "POST",
        OnSuccess = "updateSuccess"
    },
new { @id = "updateDegreeForm" }))
{
    @Html.ValidationSummary()
    <div id="update-message" class="display:none;">
    </div>
    <table>
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.Major)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.Major)
            </td>
            <td class="editor-label">
                @Html.LabelFor(model => model.Institution)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.Institution)
            </td>
        </tr>
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.Country)
            </td>
            <td class="editor-field">
                @Html.DropDownList("Country")
            </td>
            <td class="editor-label">
                @Html.LabelFor(model => model.DegreeType)
            </td>
            <td class="editor-field">
                @Html.DropDownList("DegreeType")
            </td>
        </tr>
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.CompletionYear)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.CompletionYear)
            </td>
            <td class="editor-label">
                @Html.LabelFor(model => model.Email)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.Email)
            </td>
        </tr>
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.Phone)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.Phone)
            </td>
        </tr>
    </table>  
}

как я могу позволить отображать все уровни проверки в диалоговой форме? заранее спасибо


person Monah    schedule 07.07.2011    source источник
comment
Я тоже в ситуации сохранения :(   -  person TheVillageIdiot    schedule 17.11.2012


Ответы (1)


Ну вот спустя почти 2 дня я наткнулся на решение проблемы. Скелет того, что я использую для частичного/jquery-диалога, такой же, как и у вас (который я взял из сообщения в блоге). Я изменил свой метод Create следующим образом:

[HttpPost]
public JsonResult Create(EventObject evt)
{
    if(ModelState.IsValid)
    {
        //save the model and return success
        return new JsonResult{
                                 Data = new
                                        {
                                            Result="S",
                                            Message="successfully created event"
                                        }
                            };
    }
    else
    {
        return new JsonResult{
                                Data = new
                                        {
                                            Result="E",
                                            Message=CONVERT MODELSTATE TO STRING
                                        }
                            };
    }
}

Теперь на стороне разметки у меня есть следующий div:

<div id="create-event-error"></div>

моя функция обновления выглядит следующим образом:

function updateSuccess(a) {
    if (a.Result=="S") {
        $("#update-message").html(a.Message).show().delay(3000).hide();
        $dlg.dialog('close');
    }
    else {
         var d=$("div#create-event-errors");
         d.html(a.Message).dialog({
           //VARIOUS DIALOG OPTIONS
         });
    }
}

Вместо диалога вы можете показывать ошибки так, как вам нравится.

person TheVillageIdiot    schedule 17.11.2012