1

Using [Remote] for validating following field as:

[Required]
[Remote("cnicExist", "evaluation", AdditionalFields = "id", HttpMethod = "POST", ErrorMessage = "An evaluation of probationer with this cnic already exists. Please provide another cnic.")]
public string cnic { get; set; }

View is:

<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.10.2.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-ui-1.11.4.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(model => model.id)
    <div class="form-group">
        @Html.Label("CNIC:", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.cnic, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.cnic, "")
        </div>
    </div>
}

Controller is:

[HttpPost]
    public JsonResult cnicExist(int id, string cnic)
    {
        return Json(IsUnique(id, cnic));
    }
    private bool IsUnique(int id, string cnic)
    {
        if (id == 0)
        {
            return !hc.evaluationOfProbationers.Any(x => x.cnic == cnic);
        }
        else 
        {
            return !hc.evaluationOfProbationers.Any(x => x.cnic == cnic && x.id != id);
        }
    }

HTML generated for @Html.HiddenFor(model => model.id) and @Html.EditorFor(model => model.cnic is as following:

<input data-val="true" data-val-number="The field id must be a number." data-val-required="The id field is required." id="id" name="id" type="hidden" value="" />

    <div class="form-group">
        <label class="control-label col-md-2" for="CNIC:">CNIC:</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" data-val="true" data-val-remote="An evaluation of probationer with this cnic already exists. Please provide another cnic." data-val-remote-additionalfields="*.cnic,*.id" data-val-remote-type="POST" data-val-remote-url="/evaluation/cnicExist" data-val-required="The cnic field is required." id="cnic" name="cnic" type="text" value="" />
            <span class="field-validation-valid" data-valmsg-for="cnic" data-valmsg-replace="true"></span>
        </div>
    </div>

While debugging, what I have discovered so far is, [Remote] is not firing cnicExist(). Any ideas where I might be doing it wrong?

Jogi
  • 1
  • 2
  • 14
  • 29
  • Have you also included `jquery-{version}.js`? –  Apr 21 '16 at 08:07
  • @StephenMuecke I have updated my question. Please review. Thanks – Jogi Apr 21 '16 at 08:09
  • Assuming the attribute has been applied to property `cnic`, then what you have shown should work fine. Are you getting any errors in the browser console? –  Apr 21 '16 at 08:10
  • @StephenMuecke Nothing in the browser console. While I have put a debugging stopper on line `public JsonResult cnicExist(int id, string cnic) {`, program doesn't stop there when I move my cursor from `cnic` field in the browser console which means program is never reaching `cnicExist(int id, string cnic)`. Strange. – Jogi Apr 21 '16 at 08:13
  • your AdditionalFields = "id", use public JsonResult cnicExist(int? id, string cnic){} – Imran Luhur Apr 21 '16 at 08:26
  • 1
    @RehanKhan, I have tested your code and it works fine. If its not, there is something else in your code that you have not shown us that causing the problem. –  Apr 21 '16 at 08:57
  • @StephenMuecke Can you please guide me on relevant code I need to show you? – Jogi Apr 21 '16 at 09:12
  • I have no idea what the issue could be. But if you have any scripts on your page, start by commenting them out and test it. I'm assuming also that you have not disabled client side validation (i.e. if you leave the textbox black and submit, you will get the Required error message) –  Apr 21 '16 at 09:15
  • @StephenMuecke Problem lies with having `AdditionalFields = "id"`. If I remove it from the definition, everything runs like a charm but after I add it, `cnicExist()` doesn't fire. – Jogi Apr 21 '16 at 11:42
  • That should not be a problem. Edit you question to show the actual html generated by `@Html.HiddenFor(model => model.id)` and `@Html.EditorFor(model => model.cnic, ...)` –  Apr 21 '16 at 11:44
  • @StephenMuecke Edit on the question is done. Thanks – Jogi Apr 21 '16 at 12:09
  • 1
    The reason its failing is that `id` is `null` and your generating `value=""` in the hidden input. Your `id` property is obviously `int? id` (nullable) so `null` is posted to a method which expects `int` (not nullable) and an exception is thrown. Change the method parameter to `int? id` and adjust the other code to suit (e.g. `if (id.HasValue)` etc –  Apr 21 '16 at 12:13
  • @StephenMuecke Can I ask - why is `id` coming as `null` and not `0` when I have defined id as `int` and it is actually reflected in generated `HTML` as `data-val-number="The field id must be a number."`? – Jogi Apr 21 '16 at 18:02
  • @RehanKhan, Its generating `value=""` which means your property is `int?`, not `int`. And `data-val-number` is rendered because the value (if entered) must be able to be converted to a number –  Apr 21 '16 at 22:10
  • @StephenMuecke I'm sorry but here is the definition: `[Key] public int id { get; set; }`. As far as I think its defined as `int` not `int?`. – Jogi Apr 22 '16 at 07:08
  • Are you sure your not using a view model with a nullable `id` property. A property which is `int` will not generate `value=""` when using `@Html.HiddenFor(model => model.id)` –  Apr 22 '16 at 07:11
  • @StephenMuecke I have pasted the definition as it is. Thats exactly what I am thinking how can it be defined as `int` and be interpreted as `int?`. – Jogi Apr 22 '16 at 07:21
  • @StephenMuecke I have uploaded a snap for you to see [here](http://postimg.org/image/z3cx382ev/). – Jogi Apr 22 '16 at 07:25
  • If we ignore your bad practice of not using a view model (and even worse applying a view specific validation attribute to a data model), there must be some other problem, because `@Html.HiddenFor(model => model.id)` will not generate an input with a `null` value. Even if its a new instance, it will generate `value="0"` –  Apr 22 '16 at 07:31
  • @StephenMuecke You'd probably be surprised that I've followed the exactly same pattern for at least 25 other models and there are no problems with any of them and they are all generating `value=0`. I have double checked everything and that's what made me ask you this question. I have no clue what is a view model? – Jogi Apr 22 '16 at 07:50
  • [What is ViewModel in MVC?](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) –  Apr 22 '16 at 07:51
  • @StephenMuecke Thanks. – Jogi Apr 22 '16 at 07:53
  • @StephenMuecke ViewModel is not related to my situation given above. ViewModels are good if you have to display fields from two different models. – Jogi Apr 23 '16 at 13:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110034/discussion-between-stephen-muecke-and-rehan-khan). –  Apr 23 '16 at 23:30

1 Answers1

1

your ID is Additional Field so mostly it is null use "?" some thing like that

[HttpPost]
public JsonResult cnicExist(int? id, string cnic)
{
    return Json(IsUnique(id, cnic));
}
private bool IsUnique(int? id, string cnic)
{
    if (id == 0)
    {
        return false;
    }
    else
    {
        return true;
    }
}
Imran Luhur
  • 447
  • 3
  • 15
  • You also need to fix `return Json(IsUnique(id, cnic));` line of code? – Jogi Apr 21 '16 at 08:31
  • Also, I am confused how can `id` ever be `null`? – Jogi Apr 21 '16 at 08:32
  • ID is Additional field that means if there is any value in ID it will redirect other then not... so if you are using "int id" that means it must fill any value, – Imran Luhur Apr 21 '16 at 08:38
  • `id` is always going to be there. On a new entry `id` will be equal to 0, and on Edit of an existing record `id` is confirmed to be an existing id in the database with the help of this line of code: `return !hc.evaluationOfProbationers.Any(x => x.cnic == cnic && x.id != id);`. If this logic fails, it returns falls which is what we need and we forward it to user with our error message. – Jogi Apr 21 '16 at 08:42
  • Please delete your answer or you might get negative marking. – Jogi Apr 21 '16 at 08:44
  • Please Do some research while posting questions . – Imran Luhur Apr 21 '16 at 08:45
  • you have posted this same question twice ? and i think you are starter on mvc , – Imran Luhur Apr 21 '16 at 09:04