0

有没有办法在 mvc 中没有模型的视图中验证纯 HTML 表单?

我的观点看起来像

@using (Html.BeginForm("Upload", "Picture", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()
        <a class="uploadlink" style="cursor:pointer" onclick="document.getElementById('file').click();">Open</a>
        <input type="file" name="file" id="file" style="opacity:0" onchange="document.getElementById('title').value = this.value.substring(this.value.lastIndexOf('\\') +1 );"/>
        <br />
        <input type="text" name="title" id="title" />
        <br/>
        <textarea name="desc" id="desc"></textarea>
        <br/>
        <input type="submit" value="Save" />
    }

我的控制器看起来像

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Upload(string title, string desc, HttpPostedFileBase file)
        {

            if (file == null)
            {
                return Content("<span id='result'>Please select a file first</span>");
            }
            if (string.IsNullOrEmpty(title))
            {
                return Content("<span id='result'>Please enter a name</span>");
            }
            if (file.ContentLength > 0)
            {
                var fileName = System.IO.Path.GetFileName(file.FileName);
                string c = file.FileName.Substring(file.FileName.LastIndexOf("."));
                title = title.Replace(c, "");
                byte[] uploadedFile = new byte[file.InputStream.Length];
                file.InputStream.Read(uploadedFile, 0, uploadedFile.Length);
                try
                {
                    using (MemoryStream ms = new MemoryStream(uploadedFile))
                    Image.FromStream(ms);
                }
                catch (ArgumentException)
                {
                    return Content("<span id='result'>The file you are trying to upload is not a valid image file.</span>");
                }

而不是return Content 我想知道是否有任何方法可以添加ModelState.AddError或类似的东西。

4

1 回答 1

1

是的,您可以添加ModelState.AddModelError,但在您看来,您应该使用一些 HTML 帮助程序,例如Html.ValidationSummary或者Html.ValidationMessage如果您希望显示此消息。

例如在您看来:

<input type="file" name="file" id="file" style="opacity:0" onchange="document.getElementById('title').value = this.value.substring(this.value.lastIndexOf('\\') +1 );"/>
@Html.ValidationMessage("file")

并在您的控制器操作中:

ModelState.AddModelError("file", "some error message");

显然,使用视图模型和这些助手的强类型等价物以及使用助手来生成您的标记而不是像在您的案例中那样对其进行硬编码要好得多。

你知道的,比如:

public class MyViewModel
{
    [Required(ErrorMessage = "Please select a file first")]
    public HttpPostedFileBase File { get; set; }

    [Required(ErrorMessage = "Please enter a name")]
    public string Title { get; set; }

    public string Description { get; set; }
}

在您看来,例如:

@model MyViewModel
...

@using (Html.BeginForm("Upload", "Picture", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

    <a class="uploadlink" style="cursor:pointer" onclick="document.getElementById('file').click();">Open</a>

    @Html.TextBoxFor(x => x.File, new { 
        type = "file", 
        style = "opacity:0", 
        onchange="document.getElementById('title').value = this.value.substring(this.value.lastIndexOf('\\') +1 );" 
    })
    @Html.ValidationMessageFor(x => x.File)
    <br />

    @Html.EditorFor(x => x.Title)
    @Html.ValidationMessageFor(x => x.Title)
    <br/>

    @Html.TextAreaFor(x => x.Description)
    <br/>

    <input type="submit" value="Save" />
}

并在您的控制器操作中:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(MyViewModel model)
{
    if (!ModelState.IsValid)     
    {
        return View(model);
    }

    try
    {
        Image.FromStream(model.File.InputStream);
    }
    catch (ArgumentException)
    {
        ModelState.AddModelError("File", "The file you are trying to upload is not a valid image file.");
    }

    // At this stage you know that the model is valid =>
    // you could do something with those model.Title and model.Description properties

    return RedirectToAction("Success");
}

顺便说一句,您可能会看一下following answer of mine从您的控制器操作中删除更多不属于那里的管道/验证代码。

于 2013-08-28T20:05:42.247 回答