简体   繁体   English

ASP.NET MVC验证

[英]ASP.NET MVC Validation

I have 2 scenarios that I need some help with re validation in my ASP.NET MVC application. 在ASP.NET MVC应用程序中,我有2种情况需要重新验证方面的帮助。 I'm aware that having validation within the controller is not ideal, so am looking to keep this elsewhere - perhaps with my models where I can. 我知道在控制器内进行验证并不理想,因此希望将其保留在其他地方-也许可以使用我的模型。

1) I have a model with various properties, some of which have validation against them using DataAnnotations. 1)我有一个具有各种属性的模型,其中一些属性已使用DataAnnotations对它们进行了验证。 I'm then using the Html helper methods within my view to expose any validation errors against the relevant fields. 然后,我在视图中使用Html帮助器方法来显示针对相关字段的任何验证错误。 For the most part, these work as expected. 在大多数情况下,这些工作都可以预期。 The exception I've come up against is where one of the fields in my view is a dropdown list. 我遇到的例外是我视图中的字段之一是下拉列表。 The first item within my list is empty/blank, the rest are genuine values. 我列表中的第一项为空/空白,其余均为真实值。 The property in my model that this field relates to has the following against it: 我的模型中与该字段相关的属性对此有以下要求:

[Required(ErrorMessage = "A value from the list is required")]

At present, if I leave the default value in the list (blank) and don't select a genuine value from the list, I want it to render the validation error message, but it's currently treating it as if it were a valid value, and passing that validation. 目前,如果我将默认值保留在列表中(空白),并且没有从列表中选择一个真实值,我希望它呈现验证错误消息,但它目前正在将其视为有效值,并通过验证。

How can I get it to fail validation if that blank/empty list item is submitted? 如果提交了空白/空列表项,如何使它无法通过验证?

2) On one of my views, I have a few file upload controls, enabling the user to upload images to the website. 2)根据我的一种观点,我有一些文件上传控件,使用户可以将图像上传到网站。 These fields are not directly bound to any properties within my model - only the resulting filename's (once the file has been uploaded, converted, renamed etc.) are then assigned to 'Filename1', 'Filename2' etc. properties within my model. 这些字段未直接绑定到模型中的任何属性-仅将生成的文件名(一旦文件被上传,转换,重命名等)随后分配给模型中的“ Filename1”,“ Filename2”等属性。

So, I am wondering how to best go about validating that these mandatory file uploads? 因此,我想知道如何最好地验证这些强制性文件上传? At present I am doing the following for each of the file upload controls, within my controller(!): 目前,我正在我的控制器(!)中对每个文件上传控件执行以下操作:

HttpPostedFileBase file = null;

file = Request.Files["Filename1"];
        if (file != null && file.ContentLength == 0)
                ModelState.AddModelError("Filename1", "Image1 is required");

Once this is done for each of the file upload controls, I check if the ModelState is valid: 为每个文件上传控件完成此操作后,我将检查ModelState是否有效:

if (ModelState.IsValid)

I'm sure there must be a better way of performing this validation, and I'd imagine it's not ideal to have this in the controller, but I'm not sure the best way to handle this. 我确定必须有一种更好的方法来执行此验证,并且我想在控制器中使用它不是理想的选择,但是我不确定处理此问题的最佳方法。

I'd appreciate any help with these 2 scenarios. 对于这两种情况,我将不胜感激。

For #1, what is the value that is getting posted for the dropdown list and what is the type in your model that it is trying to bind against? 对于#1,下拉列表中发布的值是什么?模型中要绑定的类型是什么? If it is posting a value like " ", then it will pass validation. 如果要发布类似“”的值,则它将通过验证。 You need to make sure it is an empty string if your type is a string. 如果您的类型是字符串,则需要确保它是一个空字符串。

For #2, you could try writing a custom model binder, but not sure how ugly that would be to get access to the files. 对于#2,您可以尝试编写自定义模型联编程序,但是不确定是否可以访问文件那么丑陋。 Another option is to make it part of your parameters on the action result: 另一种选择是使其成为操作结果中参数的一部分:

public ActionResult Test(TestModel model, HttpPostedFileBase files)

This will at least do the auto binding for you if a file exists, but you would still have to perform the manual validation like you would do before. 如果文件存在,这至少会为您进行自动绑定,但是您仍然必须像以前一样执行手动验证。 I know its not the exact answer you are looking for, but it does clean up the file code a little bit more. 我知道它不是您要查找的确切答案,但是它确实可以清除文件代码。

Also, this question might help a little more: ASP.NET MVC posted file model binding when parameter is Model 同样,此问题可能会有所帮助: 参数为Model时,ASP.NET MVC发布文件模型绑定

Here is my code (explanations later) : 这是我的代码(稍后解释):

The form: 表格:

<% using (Html.BeginForm("TestForm", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
   { %>
   <%: Html.DropDownList("ComboboxValue", new SelectList(Model.ComboboxValues)) %><br />
   <input type="file" id="FileUpload" name="FileUpload" /><br />
   <input type="submit" id="submit" name="submit" value="Valider" />
<%} %>

The model: 该模型:

public class TestFormModel
{
    [Required(ErrorMessage = "A value from the list is required")]
    public string ComboboxValue { get; set; }

    public List<string> ComboboxValues { get; set; }

    public HttpPostedFileBase FileUpload { get; set; }

    public ModelStateDictionary IsFileValid()
    {
        ModelStateDictionary modelState = new ModelStateDictionary();
        modelState.AddModelError("FileUpload", "Here is the problem.");
        return modelState;
    }

The controller : 控制器:

    public ActionResult TestForm()
    {
        TestFormModel model = new TestFormModel();
        model.ComboboxValues = new List<string>(){
            "", "Red", "Blue", "Yellow"
        };
        return View("TestForm", model);
    }
    [HttpPost]
    public ActionResult TestForm(TestFormModel model)
    {
        model.ComboboxValues = new List<string>(){
            "", "Red", "Blue", "Yellow"
        };
        ModelState.Merge(model.IsFileValid());
        return View("TestForm", model);
    }

1) If you have a null value, your model wont be valid. 1)如果值为空,则您的模型将无效。

2) To avoid Request.Files["Filename1"]; 2)避免Request.Files [“ Filename1”]; you can "type" your form (new { enctype = "multipart/form-data" }). 您可以“键入”表单(新的{enctype =“ multipart / form-data”})。 With this, your model will contain the file. 这样,您的模型将包含文件。 You can add an extension method, for example : 您可以添加扩展方法,例如:

public static bool IsCSVValid(this HttpPostedFileBase file)
{
    return (file != null && file.ContentLength != 0 && file.FileName.EndsWith(".CSV", StringComparison.InvariantCultureIgnoreCase));
}

And you can add error from somewhere with ModelState.Merge(). 您可以使用ModelState.Merge()从某个地方添加错误。

I dont know if it's a "good thing to do", but it works pretty well :) 我不知道这是否是一件“好事”,但是效果很好:)

It seam like you are working on ASP.net Dynamic data. 就像您正在使用ASP.net动态数据一样。 If yes, ASP.Net Dynamic data work on the concept Module view control. 如果是,则ASP.Net Dynamic数据将在概念模块视图控件上工作。

In MVC Loading a control for a column depend on the metadata of a class. 在MVC中,加载列的控件取决于类的元数据。 It read the data type of the class and then load control accordingly. 它读取类的数据类型,然后相应地加载控件。 If you make any changes to these control will affect other places as will. 如果对这些控件进行任何更改,则将同样影响其他地方。

Top handle this you should create new control and do the validation in that control and in class for that column you can specify that it should use your customized control. 最好的方法是,您应该创建新的控件并在该控件中进行验证,并且在该列的类中,您可以指定它应使用自定义控件。

Please let me know if you need more details on how to customize control. 如果您需要有关如何自定义控件的更多详细信息,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM