jwaliszko / ExpressiveAnnotations

Annotation-based conditional validation library.
MIT License
351 stars 123 forks source link

RequiredIf HttpPostedFileBase issue #131

Closed TheLostBigBoss closed 8 years ago

TheLostBigBoss commented 8 years ago

Hi, I'm having issue using the RequiredIf validation for a parameter of type HttpPostedFileBase. I have installed and confirmed that EA is installed correctly, it functions with other types such as strings within the same model.

Is there any way to get this to work with checking if the user has uploaded a file?

Thanks for your time.

jwaliszko commented 8 years ago

Hi, post the details here please. The minimal yet working sample would be much valuable to save my time. As soon as I get such an archive, or at least when complete code snippets appear in this thread, I'll try to help you.

TheLostBigBoss commented 8 years ago

Here is the models being used

public class AddTestStepParametersModel
    {
        public AddTestStepParametersModel()
        {
            this.TestStepXmlParameterDefinitions = new List<TestStepParameterDefinition>();
            this.AddTestStepXmlParameterModels = new List<AddTestStepXmlParameterModel>();
        }

        public List<TestStepParameterDefinition> TestStepXmlParameterDefinitions { get; set; } 

        public List<AddTestStepXmlParameterModel> AddTestStepXmlParameterModels { get; set; }

        public string SelectedTestStepValue { get; set; }

        public int XmlParameterCount()
        {
            return this.TestStepXmlParameterDefinitions.Count();
        }
    }
public class AddTestStepXmlParameterModel
    {

        public ParameterTypeEnum ParameterType { get; set; }

        public string ParameterName { get; set; }

        public string Description { get; set; }

        [AssertThat("BindingExists == false", ErrorMessage = ""An Xml file is required to save this test step"")]
        [FileExtensions(Extensions = "xml", ErrorMessage = "Specify an XML file.")]
        public HttpPostedFileBase XmlValue { get; set; }

        [RequiredIf("BindingExists == false", ErrorMessage = "Testing EA validation")]
        public string TestParam { get; set; }

        public bool BindingExists { get; set; }

    }

Main View (relevant code)

@model Models.AddTestSuiteViewModel

<head>
    <script src="~/Scripts/jquery-3.1.0.js"></script>
    <script src="~/Scripts/jquery.validate.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
    <script src="~/Scripts/expressive.annotations.validate.js"></script>
</head>

@Html.Partial("MainTestStepTable", Model)

Partial View

@{
   int i = 0;
}
@foreach (var testStep in Model.MainTestSteps)
{
    @using (Html.BeginForm("EditTestStep", "TestSuites", FormMethod.Post, new {enctype = "multipart/form-data"}))
    {
        <div>
         @Html.EditorFor(m => Model.MainTestSteps[i].AddTestStepParametersModel)
        </div>

        <div class="modal-footer">
        <button onclick="if (this.getAttribute('clicked') == '1') { return false; } else { this.setAttribute('clicked', '1'); }" type="submit" name="addTestStepButton" value="Save" class="AddTestSuiteButton">Save</button>
        </div>
    }
}

EditorTemplate: AddTestStepParametersModel


@model Models.AddTestStepParametersModel

for (int k = 0; k < Model.XmlParameterCount(); k++)
    {
        <div>
            <br />
            @Html.HiddenFor(m => m.AddTestStepXmlParameterModels[k].ParameterName, new { @Value = Model.TestStepXmlParameterDefinitions[k].Name })
            @Html.HiddenFor(m => m.AddTestStepXmlParameterModels[k].Description, new { @Value = Model.TestStepXmlParameterDefinitions[k].Description })
            @Html.HiddenFor(m => m.AddTestStepXmlParameterModels[k].ParameterType, new { @Value = Model.TestStepXmlParameterDefinitions[k].ParameterType })

            @Html.LabelFor(m => m.AddTestStepXmlParameterModels[k].ParameterName, "Parameter Name: " + @Model.TestStepXmlParameterDefinitions[k].Name, htmlAttributes: new { @class = "control-label" })
            <br />
            <div class="col-md-4">
                <div class="form-group">
                    @Html.TextBoxFor(m => m.AddTestStepXmlParameterModels[k].XmlValue, new { type = "file", @class = "btn btn-default btn-file", style = "color:transparent", onchange = "this.style.color = 'black'"})
                    @Html.ValidationMessageFor(m => m.AddTestStepXmlParameterModels[k].XmlValue, "", new { @class = "text-danger" })

                </div>
            </div>

            <div class="col-md-3">
                <div class="form-group">
                    @Html.LabelFor(m => m.ParameterRepositoryDataCheckViewModelList[k].RepositoryDataExist, "Data Exist in Database?")
                    @Html.CheckBoxFor(m => m.ParameterRepositoryDataCheckViewModelList[k].RepositoryDataExist, new { disabled = "disabled" })
                </div>
            </div>
        </div>
    }

The above Editor Template fails to call for a valiation/verification on the condition of the bool being false.

However, in the below code, it does call validation when using the TestParam parameter and the error message pops up after leaving focus of the text box when using the same Editor Template and calls to it.

<div class="form-group">
    @Html.TextBoxFor(m => m.AddTestStepXmlParameterModels[k].TestParam)
    @Html.ValidationMessageFor(m => m.AddTestStepXmlParameterModels[k].TestParam, "", new { @class = "text-danger" })

</div>

I have verified that the BindingExists parameter is false when being passed into the model via controller/service calls, which is then passed to the view.

jwaliszko commented 8 years ago

This is far from self-sustained example. I expected something which I can paste-and-run.