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.ValidationSummaryHtml.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 に答える