I had to do some kind of duplication check of data when creating an entry (lets say username). I did it by this. (It's in VB, but don't bother)
In controller:
Function CheckForDuplication(ByVal UserName As String) As JsonResult
If db.Users.Count(Function(x) x.Username.ToLower() = UserName.ToLower()) > 0 Then
Return Json(False, JsonRequestBehavior.AllowGet)
Else
Return Json(True, JsonRequestBehavior.AllowGet)
End If
End Function
and in model:
<Remote("CheckForDuplication", "User", HttpMethod:="POST", ErrorMessage:="username not available")>
Public Property Username As String
and using standard JS validation libraries in view.
It works real fine... when creating. The trouble is that when editing you can't save back the same username because it's forbidden be the client-side validation.. as it already exist in DB. How can the validation be over-passed for current 'username' but remain for others. Or it should be redone with custom JS and [remote] removed from model. Thank you
I found out a solution to my problem by myself. I'll post it if someone else needs it. It's not very pretty one but works fine. What I've done is that when I call the View to edit I pass a TempData["name"]. And when edit the field and JS calls the CheckForDuplication method I can read the content of TempData["name"] (TempData seems to 'survive' the transition from View back to controller method, unlike ViewBag and ViewData) And when the check for duplication is made whit TempData["name"] in mind. The problem is that in that first check TempData is wiped clean (lifespan seems to be one request long) so.... I also pass a ViewBag.name to the View and made a JS script which calls a method that re set TempData["name"] with the value of ViewBag.name (since TempData["name"] can be set only server side)
Controller
Public Function Edit(UserId As Integer) As ViewResult
Dim user As User= context.User.Find(UserId)
ViewBag.UserName = user.UserName
TempData("UserName") = user.UserName
Return View(user)
End Function
'''''''''''
Function CheckForDuplicationUserName(ByVal UserName As String) As JsonResult
If context.User.Count(Function(x) x.UserName.ToLower() = UserName.ToLower()) = 0 Then
Return Json(True, JsonRequestBehavior.AllowGet)
ElseIf TempData("UserName") Is Nothing Then
Return Json(False, JsonRequestBehavior.AllowGet)
ElseIf TempData("UserName").ToString().ToLower() = UserName.ToLower() Then
Return Json(True, JsonRequestBehavior.AllowGet)
Else : Return Json(False, JsonRequestBehavior.AllowGet)
End If
End Function
''''''''''
<HttpPost>
<AllowAnonymous>
Function SetTempData(ByVal name As String)
TempData("UserName") = name
End Function
View
<script type="text/javascript">
function ResetTempData() {
var url = "/User/SetTempData";
var TDname = "@ViewBag.UserName"
$.post(url, { name: TDname});
};
$('#UserName').change(ResetTempData);
</script>
Looks very strange but works. I hope it comes handy to someone