I am coding a MVC 5 internet application and have a question regarding validation in a view.
Here is my view code:
<div class="form-group">
@Html.LabelFor(model => model.asset.linkFromExternalResource, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.asset.linkFromExternalResource)
@Html.ValidationMessageFor(model => model.asset.linkFromExternalResource, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.asset.webAddress, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.asset.webAddress, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.asset.webAddress, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.fileId, "fileId", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("fileId", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.fileId, "", new { @class = "text-danger" })
</div>
</div>
How can I write the code to validate either the model.asset.webAddress
or the model.fileId
depending on if the model.asset.linkFromExternalResource
is checked or not?
I will try and explain that better. If the user has the model.asset.linkFromExternalResource
checkbox checked, then the model.asset.webAddress
value will be validated, but not the model.fileId
and if the model.asset.linkFromExternalResource
checkbox is unchecked, then the model.asset.webAddress
value will be not be validated, but the model.fileId
will be validated.
How should I approach this situation? Do I write this code in the view, or in the controller?
EDIT
I have added MVC Foolproof Validation
but am getting the following error:
[NotImplementedException: The method or operation is not implemented.]
At this line of code:
await db.SaveChangesAsync();
Rather than using MVC Foolproof Validation
, is it easier to write my own custom validation attribute?
EDIT2
I have created a testModel, and a controller and the error still occurs.
Here is my model:
public class TestModel
{
[Key]
public int Id { get; set; }
[Required]
public string name { get; set; }
public bool testValue { get; set; }
[RequiredIfTrue("testValue")]
public string value1 { get; set; }
[RequiredIfFalse("testValue")]
public string value2 { get; set; }
}
Here is the controller:
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,name,testValue,value1,value2")] TestModel testModel)
{
if (ModelState.IsValid)
{
db.testModels.Add(testModel);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(testModel);
}
Here is the error:
Server Error in '/' Application.
The method or operation is not implemented.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NotImplementedException: The method or operation is not implemented.
Source Error:
Line 54: {
Line 55: db.testModels.Add(testModel);
Line 56: await db.SaveChangesAsync();
Line 57: return RedirectToAction("Index");
Line 58: }
Source File: e:\CanFindLocation\MVC\CanFindLocation\CanFindLocation\Controllers\TestModelsController.cs Line: 56
Stack Trace:
[NotImplementedException: The method or operation is not implemented.]
Foolproof.ModelAwareValidationAttribute.IsValid(Object value) +59
System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext) +115
System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext) +29
System.Data.Entity.Internal.Validation.ValidationAttributeValidator.Validate(EntityValidationContext entityValidationContext, InternalMemberEntry property) +198
[DbUnexpectedValidationException: An unexpected exception was thrown during validation of 'value1' when invoking Foolproof.RequiredIfTrueAttribute.IsValid. See the inner exception for details.]
System.Data.Entity.Internal.Validation.ValidationAttributeValidator.Validate(EntityValidationContext entityValidationContext, InternalMemberEntry property) +299
System.Data.Entity.Internal.Validation.PropertyValidator.Validate(EntityValidationContext entityValidationContext, InternalMemberEntry property) +148
System.Data.Entity.Internal.Validation.EntityValidator.ValidateProperties(EntityValidationContext entityValidationContext, InternalPropertyEntry parentProperty, List`1 validationErrors) +203
System.Data.Entity.Internal.Validation.TypeValidator.Validate(EntityValidationContext entityValidationContext, InternalPropertyEntry property) +105
System.Data.Entity.Internal.Validation.EntityValidator.Validate(EntityValidationContext entityValidationContext) +55
System.Data.Entity.Internal.InternalEntityEntry.GetValidationResult(IDictionary`2 items) +295
System.Data.Entity.DbContext.ValidateEntity(DbEntityEntry entityEntry, IDictionary`2 items) +86
System.Data.Entity.DbContext.GetValidationErrors() +290
System.Data.Entity.Internal.InternalContext.SaveChangesAsync(CancellationToken cancellationToken) +150
System.Data.Entity.Internal.LazyInternalContext.SaveChangesAsync(CancellationToken cancellationToken) +75
System.Data.Entity.DbContext.SaveChangesAsync(CancellationToken cancellationToken) +60
System.Data.Entity.DbContext.SaveChangesAsync() +63
CanFindLocation.Controllers.<Create>d__7.MoveNext() in e:\CanFindLocation\MVC\CanFindLocation\CanFindLocation\Controllers\TestModelsController.cs:56
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21
System.Threading.Tasks.TaskHelpersExtensions.ThrowIfFaulted(Task task) +61
System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +114
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult) +66
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +47
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +136
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +49
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +117
System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +323
System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +44
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +47
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +136
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +50
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +72
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +185
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +42
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +34
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +39
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +62
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +39
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9651116
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155