using a custom attribute on viewmodel httpfilebase property to check file extensions not working

StackOverflow https://stackoverflow.com/questions/19100634

문제

I'm using .net 4.0 so can't utilize the built in FileExtensions attribute.

I'm trying to roll up my own validation but running into a stumbling block. I found this article which looks to be a good resource: http://blog.tomasjansson.com/creating-custom-unobtrusive-file-extension-validation-in-asp-net-mvc-3-and-jquery

but alas, my object (value) is always coming in as null. the only thing I'm doing differently is I'm not using the HttpPostedFileBase as my model, I'm using my viewmodel which has a few other properties.

any ideas how I can populate my object in the IsValid overload so that I can check it?

Here is my code which is more or less a copy and paste from that article with the exception that I've got more in my viewmodel:

ViewModel:

public class Mp3ViewModel
{
    public string FileName { get; set; }
    public string FilePath { get; set; }
    [Required(ErrorMessage="You must enter a description of the MP3")]
    [Display(Name = "Description of MP3:")]
    public string Description { get; set; }
    [Required(ErrorMessage = "You must enter a job role")]
    [Display(Name = "Job Role:")]
    public string CallJobRole { get; set; }
    [Required(ErrorMessage = "You must enter a call outcome")]
    [Display(Name = "Call Outcome:")]
    public string CallOutcome { get; set; }
    [Required(ErrorMessage = "You must enter a call type")]
    [Display(Name = "Call Type:")]
    public string CallType { get; set; }
    [Required(ErrorMessage = "You must enter a call section")]
    [Display(Name = "Call Section:")]
    public string CallSection { get; set; }
    [Required(ErrorMessage = "You must enter call comments")]
    [Display(Name = "Call Comments:")]
    public string CallComments { get; set; }
    [Required(ErrorMessage = "You must enter call keywords")]
    [Display(Name = "Call Keywords (separate by comma):")]
    public string CallKeywords { get; set; }
    [Required(ErrorMessage = "You must select a file")]
    [Display(Name = "Select an MP3 to upload:")]
    [FileExtensions("txt|doc")]
    public HttpPostedFileBase Mp3 { get; set; }
}

Custom Attribute Validation:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FileExtensionsAttribute : ValidationAttribute
{
    private List<string> ValidExtensions { get; set; }

    public FileExtensionsAttribute(string fileExtensions)
    {
        ValidExtensions = fileExtensions.Split('|').ToList();
    }

    public override bool IsValid(object value)
    {
        HttpPostedFileBase file = value as HttpPostedFileBase;
        if (file != null)
        {
            var fileName = file.FileName;
            var isValidExtension = ValidExtensions.Any(y => fileName.EndsWith(y));
            return isValidExtension;
        }
        return true;
    }
}

View:

@model CallLibrary.BO.ViewModels.Mp3ViewModel
@{
    ViewBag.Title = "Call Library Administration";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@section scripts
{
    <script src="~/Scripts/jquery.validate.min.js" type="text/javascript"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
}

<h2>Call Library Administration</h2>
@ViewBag.test
@using (Html.BeginForm())
{
<div>
@Html.ValidationMessageFor(x => x.Description)<br />
@Html.LabelFor(x => x.Description)
@Html.TextAreaFor(x => x.Description)

</div>
<div>
@Html.ValidationMessageFor(x => x.CallJobRole)<br />
@Html.LabelFor(x => x.CallJobRole)
@Html.TextBoxFor(x => x.CallJobRole)

</div>
<div>
@Html.ValidationMessageFor(x => x.CallOutcome)<br />
@Html.LabelFor(x => x.CallOutcome)
@Html.TextBoxFor(x => x.CallOutcome)

</div>
<div>
@Html.ValidationMessageFor(x => x.CallType)<br />
@Html.LabelFor(x => x.CallType)
@Html.TextBoxFor(x => x.CallType)

</div>
<div>
@Html.ValidationMessageFor(x => x.CallSection)<br />
@Html.LabelFor(x => x.CallSection)
@Html.TextBoxFor(x => x.CallSection)

</div>
<div>
@Html.ValidationMessageFor(x => x.CallComments)<br />
@Html.LabelFor(x => x.CallComments)
@Html.TextAreaFor(x => x.CallComments)

</div>
<div>
@Html.ValidationMessageFor(x => x.CallKeywords)<br />
@Html.LabelFor(x => x.CallKeywords)
@Html.TextAreaFor(x => x.CallKeywords)

</div>
    <div>
    @Html.ValidationMessageFor(x=>x.Mp3)<br />
    @Html.LabelFor(x=>x.Mp3)
    @Html.TextBoxFor(x=>x.Mp3, new {type= "file"})
    </div>
 <div>
 <input type="submit" value="Add MP3" />
 </div>   
}

any suggestions would be greatly appreciated. TIA

도움이 되었습니까?

해결책

doh! my bad. I wasn't using a form with multipart form data. when I added that, all is good in the world.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top