Free check in MVC: specify RuleSet for check on client side

In my ASP.NET MVC 4 project, I have a validator for one of my view models that contains the rule definition for RuleSets. Editused in the Post action when all client checks passed. Urland the Emailrules set the rules used in the Editruleset (you can see it below) and in special ajax actions that check only email and only Url respectively.

My problem is that the view does not know that it should use the ruleset Editto generate the html attributes of the client and use the ruleset defaultthat is empty. How can I show that a view uses a set of rules Editto generate input attributes?

Model:

public class ShopInfoViewModel
{
    public long ShopId { get; set; }

    public string Name { get; set; }

    public string Url { get; set; }

    public string Description { get; set; }

    public string Email { get; set; }
}

Validator:

public class ShopInfoViewModelValidator : AbstractValidator<ShopInfoViewModel>
{
    public ShopInfoViewModelValidator()
    {
        var shopManagementService = ServiceLocator.Instance.GetService<IShopService>();

        RuleSet("Edit", () =>
        {
            RuleFor(x => x.Name)
                .NotEmpty().WithMessage("Enter name.")
                .Length(0, 255).WithMessage("Name length should not exceed 255 chars.");

            RuleFor(x => x.Description)
                .NotEmpty().WithMessage("Enter name.")
                .Length(0, 10000).WithMessage("Name length should not exceed 10000 chars.");

            ApplyUrlRule(shopManagementService);
            ApplyEmailRule(shopManagementService);
        });

        RuleSet("Url", () => ApplyUrlRule(shopManagementService));
        RuleSet("Email", () => ApplyEmailRule(shopManagementService));
    }

    private void ApplyUrlRule(IShopService shopService)
    {
        RuleFor(x => x.Url)
            .NotEmpty().WithMessage("Enter url.")
            .Length(4, 30).WithMessage("Length between 4 and 30 chars.")
            .Matches(@"[a-z\-\d]").WithMessage("Incorrect format.")
            .Must((model, url) => shopService.Available(url, model.ShopId)).WithMessage("Shop with this url already exists.");
    }

    private void ApplyEmailRule(IShopService shopService)
    {
        // similar to url rule: not empty, length, regex and must check for unique
    }
}

Example validation action:

 public ActionResult ValidateShopInfoUrl([CustomizeValidator(RuleSet = "Url")]
        ShopInfoViewModel infoViewModel)
 {
     return Validation(ModelState);
 }

Receive and send actions for ShopInfoViewModel:

[HttpGet]
public ActionResult ShopInfo()
{
    var viewModel = OwnedShop.ToViewModel();
    return PartialView("_ShopInfo", viewModel);
}

[HttpPost]
public ActionResult ShopInfo(CustomizeValidator(RuleSet = "Edit")]ShopInfoViewModel infoViewModel)
    {
        var success = false;

        if (ModelState.IsValid)
        {
            // save logic goes here
        }
    }

The view contains the following code:

@{
    Html.EnableClientValidation(true);
    Html.EnableUnobtrusiveJavaScript(true);
}
<form class="master-form" action="@Url.RouteUrl(ManagementRoutes.ShopInfo)" method="POST" id="masterforminfo">
    @Html.TextBoxFor(x => x.Name)
    @Html.TextBoxFor(x => x.Url, new { validationUrl = Url.RouteUrl(ManagementRoutes.ValidateShopInfoUrl) })
    @Html.TextAreaFor(x => x.Description)
    @Html.TextBoxFor(x => x.Email, new { validationUrl = Url.RouteUrl(ManagementRoutes.ValidateShopInfoEmail) })
    <input type="submit" name="asdfasfd" value="" style="display: none">
</form>

The result of html input (without any client validation attributes):

<input name="Name" type="text" value="Super Shop"/> 
+4
source share
2 answers

FluentValidation . , , , , RuleSetForClientSideMessagesAttribute:

[HttpGet]
[RuleSetForClientSideMessages("Edit")]
public ActionResult ShopInfo()
{
    var viewModel = OwnedShop.ToViewModel();
    return PartialView("_ShopInfo", viewModel);
}

- :

[RuleSetForClientSideMessages("Edit", "Email", "Url")]
public ActionResult ShopInfo()
{
    var viewModel = OwnedShop.ToViewModel();
    return PartialView("_ShopInfo", viewModel);
}

, , FluentValidation, HttpContext (RuleSetForClientSideMessagesAttribute ):

public ActionResult ShopInfo(validateOnlyEmail)
{
    var emailRuleSet = new[]{"Email"};
    var allRuleSet = new[]{"Edit", "Url", "Email"};

    var actualRuleSet = validateOnlyEmail ? emailRuleSet : allRuleSet;
    filterContext.HttpContext.Items["_FV_ClientSideRuleSet"] = actualRuleSet;

    return PartialView("_ShopInfo", viewModel);
}

, .

+6

, ​​ ...

7.4.0, ;

ControllerContext.SetRulesetForClientsideMessages("ruleset1", "ruleset2" /*...etc*);
0

All Articles