warrenbuckley / Umbraco-Validation-Attributes

This project is custom ASP.NET MVC Validation Attributes for Models, that allows error messages to be regionalised with dictionary items from Umbraco.
25 stars 9 forks source link

Umbraco Validation Attributes plugin fails to load dictionary values in Umbraco v7.1.9 + #25

Open J35P1N opened 9 years ago

J35P1N commented 9 years ago

I have been using this package with Umbraco v7 for some time all the way up to 7.1.6 but after recently starting a new project in v7.1.9 I have found that the support is patchy.

@UmbracoValidationHelper.GetDictionaryItem("itemName") appears to function correctly however when using the following model:

public class NewsletterModel
{
    [UmbracoEmail(ErrorMessageDictionaryKey = "Newsletter.Error.Email")]
    [UmbracoRequired("Newsletter.Error.Required")]
    [UmbracoDisplayName("Newsletter.Email")]
    public string EMAIL { get; set; }

    [UmbracoRequired("Newsletter.Error.Required")]
    [UmbracoDisplayName("Newsletter.Forename")]
    public string MMERGE4 { get; set; }

    [UmbracoRequired("Newsletter.Error.Required")]
    [UmbracoDisplayName("Newsletter.Surname")]
    public string LNAME { get; set; }
}

And the following method of rendering the label in the view:

<div class="form-group clearfix">
    @Html.LabelFor(model => model.MMERGE4, new { @class = "control-label col-md-3" })
    <div class="col-md-9">
        @Html.TextBoxFor(model => model.MMERGE4, new { @class = "form-control input-sm", aria_required = "true", required = "true" })
    </div>

    @Html.ValidationMessageFor(model => Model.MMERGE4)
</div>

no labels are presented meaning the dictionary retrieval method may need altering. I have tried updating the package dependencies using NuGet as a last ditch attempt to get it to work but updating the UmbracoCms.Core to 7.1.9 does nothing and trying to update all of the other dependencies produces the following error:

Install failed. Rolling back...
Updating 'Microsoft.AspNet.Mvc 4.0.30506.0' to 'Microsoft.AspNet.Mvc 5.2.2' failed. Unable to find a version of 'UmbracoCms.Core' that is compatible with 'Microsoft.AspNet.Mvc 5.2.2'.
warrenbuckley commented 9 years ago

I would have to step through & debug this on an Umbraco 7.1.9 & 7.2 site to test & verify this.

KasperHolm commented 9 years ago

I dont know if, umbraco is suporting MVC 5.

Are you posting the model to a surface controller ?

warrenbuckley commented 9 years ago

Hi @JasonEspin I would agree with @KasperHolm here as I am sure that the Umbraco core does not support MVC5 officially yet. So with your project type being set to MVC5 this is most likely not going to work.

Warren

J35P1N commented 9 years ago

Hi @warrenbuckley I'm not using MVC5 in my project though as you can see below:

<dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
  </dependentAssembly>

I only mentioned MVC5 as that is what happens when I try and update all of the package dependencies for the validation attributes project via NuGet. I've even tried downloading a fresh copy from the Git repo and using that in my project with no modification and that doesn't work either.

KasperHolm commented 9 years ago

@JasonEspin Are you returning, the view via a surfacecontroller og in a rendercontroller =?

J35P1N commented 9 years ago

@KasperHolm No, the view is rendered using a Partial view which is then passed into a Macro. This is the way I've always done it and is also the way they recommend in the Umbraco Lvl 2 certification course.

@using JesperHannibal.Controllers
@using Newtonsoft.Json
@using Newtonsoft.Json.Linq
@using UmbracoValidationAttributes
@model JesperHannibal.Models.NewsletterModel

@if (TempData["success"] == null)
{
using (Html.BeginUmbracoForm<NewsletterController>("Submit"))
{
        <div class="form-group clearfix">
            @Html.LabelFor(model => model.EMAIL, new { @class = "control-label col-md-3" })
            <div class="col-md-9">
                @Html.TextBoxFor(model => model.EMAIL, new { @class = "form-control input-sm", aria_required = "true", required = "true", type = "email", placeholder = "your@email.address" })
            </div>

            @Html.ValidationMessageFor(model => Model.EMAIL)
        </div>
        <div class="form-group clearfix">
            @Html.LabelFor(model => model.MMERGE4, new { @class = "control-label col-md-3" })
            <div class="col-md-9">
                @Html.TextBoxFor(model => model.MMERGE4, new { @class = "form-control input-sm", aria_required = "true", required = "true" })
            </div>

            @Html.ValidationMessageFor(model => Model.MMERGE4)
        </div>
        <div class="form-group clearfix">
            @Html.LabelFor(model => model.LNAME, new { @class = "control-label col-md-3" })
            <div class="col-md-9">
                @Html.TextBoxFor(model => model.LNAME, new { @class = "form-control input-sm", aria_required = "true", required = "true" })
            </div>

            @Html.ValidationMessageFor(model => Model.LNAME)
        </div>
        <div class="form-group clearfix">
            <div style="position: absolute; left: -5000px;"><input type="text" name="code" tabindex="-1" value=""></div>
            <div class="col-md-12">
                <button type="submit" class="btn btn-default btn-warning pull-right">
                    @UmbracoValidationHelper.UmbracoHelper.GetDictionaryValue("Buttons.Submit")
                </button>
            </div>
        </div>
}
}else{
<div class="col-md-12">
    @UmbracoValidationHelper.UmbracoHelper.GetDictionaryValue("Newsletter.Confirm")
    <br/><br/>
</div>
}
warrenbuckley commented 9 years ago

@JasonEspin from that same partial can you try & retrieve the dictionary keys as per normal please. I am curious to see if there is any issues or problems there currently?!

KasperHolm commented 9 years ago

@JasonEspin Okay, that is wierd. im just covering the basics here, have you set a language in the site in umbraco ? :)

J35P1N commented 9 years ago

@warrenbuckley You cannot retrieve the dictionary keys as normal via this method because the partial does not inherit from Umbraco.Web.Mvc.UmbracoTemplatePage like a normal partial would because we are using the @model JesperHannibal.Models.NewsletterModel definition here. You cannot use both.

I am able to retrieve the dictionary values using

@UmbracoValidationHelper.GetDictionaryItem("Newsletter")

and have used this as a workaround in the meantime as follows:

<div class="form-group clearfix">
        <label for="MMERGE4" class="control-label col-md-3">@UmbracoValidationHelper.GetDictionaryItem("Newsletter.Forename")</label>
        <div class="col-md-9">
            @Html.TextBoxFor(model => model.MMERGE4, new { @class = "form-control input-sm", aria_required = "true", required = "true" })
        </div>

        @Html.ValidationMessageFor(model => Model.MMERGE4)
    </div>

But I really don't like having to do this in this way. I haven't tried whether or not the validation messages are coming through yet either as I haven't got to that stage of my testing yet.

J35P1N commented 9 years ago

@KasperHolm No, I have not but I have never had to before and this has worked so I do not believe that is the issue.

KasperHolm commented 9 years ago

@JasonEspin hmm Could you try? i do belive that if it's not set it will default back to the computer / servers language, and if thats not the one you're using in umbraco it migth cause some trouble.

J35P1N commented 9 years ago

@KasperHolm Unfortunately, that doesn't make any difference.

warrenbuckley commented 9 years ago

@JasonEspin it is possible to inherit your ViewModel like so

public class ContactFormViewModel:RenderModel You should then get Umbraco.GetDictionaryValue() available to use etc...

J35P1N commented 9 years ago

@warrenbuckley Sorry, where would that code go?

warrenbuckley commented 9 years ago

Partial View reference http://our.umbraco.org/documentation/Reference/Templating/Mvc/partial-views

warrenbuckley commented 9 years ago

So can you show me your class/model for this please JesperHannibal.Models.NewsletterModel

J35P1N commented 9 years ago

Sure. Here you go

using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web;
using UmbracoValidationAttributes;

namespace JesperHannibal.Models
{
    public class NewsletterModel
    {
        [UmbracoEmail(ErrorMessageDictionaryKey = "Newsletter.Error.Email")]
        [UmbracoRequired("Newsletter.Error.Required")]
        [UmbracoDisplayName("Newsletter.Email")]
        public string EMAIL { get; set; }

        [UmbracoRequired("Newsletter.Error.Required")]
        [UmbracoDisplayName("Newsletter.Forename")]
        public string MMERGE4 { get; set; }

        [UmbracoRequired("Newsletter.Error.Required")]
        [UmbracoDisplayName("Newsletter.Surname")]
        public string LNAME { get; set; }
    }
}
warrenbuckley commented 9 years ago

using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Application.Common.Helpers; using Application.Common.Validation; using Umbraco.Core.Models; using Umbraco.Web; using Umbraco.Web.Models;

namespace Application.Common.Model.ViewModels { public class ContactFormViewModel:RenderModel, IValidatableObject { public ContactFormViewModel() : base(UmbracoContext.Current.PublishedContentRequest.PublishedContent) {

    }

    public ContactFormViewModel(IPublishedContent content)
        : base(content)
    {

    }

    [UmbracoDisplayName("Site.Pages.Contact.Title")]
    [UmbracoRequired(ErrorMessageDictionaryKey = "Site.Pages.Contact.Required")]
    public string Title { get; set; }

    [UmbracoDisplayName("Site.Pages.Contact.Name")]
    [UmbracoRequired(ErrorMessageDictionaryKey = "Site.Pages.Contact.Required")]
    public string Name { get; set; }

    public string Region { get; set; }

    [UmbracoDisplayName("Site.Pages.Contact.Surname")]
    public string Surname { get; set; }

    [UmbracoDisplayName("Site.Pages.Contact.Email")]
    [UmbracoRequired(ErrorMessageDictionaryKey = "Site.Pages.Contact.Required")]
    [UmbracoEmail(ErrorMessageDictionaryKey = "Site.Pages.Contact.InvalidEmail")]
    public string Email { get; set; }

    [UmbracoDisplayName("Site.Pages.Contact.Message")]
    [UmbracoRequired(ErrorMessageDictionaryKey = "Site.Pages.Contact.Required")]
    public string Message { get; set; }

    [UmbracoDisplayName("Site.Pages.Contact.AgreeTerms")]
    [UmbracoMustBeTrue(ErrorMessageDictionaryKey = "Site.Pages.Contact.Required")]
    public bool AcceptedTerms { get; set; }

    public bool OptIntoFurtherInfo { get; set; }
}

}

J35P1N commented 9 years ago

@warrenbuckley BTW, in the Macro that renders the partial view, I am doing the following

@inherits Umbraco.Web.Macros.PartialViewMacroPage
@using JesperHannibal.Models;
@{Html.RenderPartial("Newsletter", new NewsletterModel());}

I believe this is what you mean by inheriting the view model. Again this is the way I was taught to do it in the Umbraco level 2 course.

warrenbuckley commented 9 years ago

There are many ways to skin a cat & do the same thing :) You have said you have had this working previously. Is there anything you have done differently this time around?

J35P1N commented 9 years ago

@warrenbuckley Nope. Everything is the same. This is actually an update to the previous version of the website that I created. I started a new project, and new Umbraco installation and moved my code across. There has been no modification to the code (other than ensuring the using statement matches the correct model references etc) that was working on the previous version of the site. The only difference is that now the Umbraco version is 7.1.9

J35P1N commented 9 years ago

@warrenbuckley Is this still being looked into or has the thread gone cold? I've tried it with a fresh installation of 7.2 also and it doesn't work

stefanoberetta commented 9 years ago

Hi guys! I have the same problem and I noticed a strange beahviour of the application. I don't know if this can help, but anyway: I have a multilingual website, two branch with both domain and language setted. I have a partial for the login, inserted in my umbraco template with a Html.Partial("LoginPartial",new CustomLoginModel()). The Model has its own properties with the UmbracoRequired and UmbracoDisplayName attributes. When the application is rebuilt (due to a replaced dll or a change to the web.config) and I navigate to the french login page, the plugin loads the dictionaries correctly, but when I navigate to the login page of the other language the dictionaries are the same of the previous page. It seems the application keep in memory the first dictionaries loaded when the application is built. I'm running U7.1.9 and I also tested it on 7.2.1 and 7.1.8, same behaviour...

craigacronin commented 9 years ago

Hi All, I'm just building a bilingual site using 7.2.1 and seeing the same problem as stefan. I am also seeing the same problem in the example site provided by Warren.

Once I rebuild the site, I will see the dictionary values from the first language I activate. Any solutions/workarounds would be great.

The attribute set itself is excellent and would be great in the core.

craigacronin commented 9 years ago

I've been looking at this issue more and stepping through Warren's source code for the project. If I take the UmbracoRequired attribute for example I can see that the instantiation only runs on first build and accessing the attribute. Every other request then just runs the GetClientValidationRules method.

chris64digital commented 9 years ago

I've built a pretty large multi-language site using this code and upgraded the version of umbraco because I needed something from 7.2 and am now having this same issue too. It looks like Umbraco might be caching the labels/errors. Not good!

chris64digital commented 9 years ago

Putting something like this: @library.GetDictionaryItem("Forms.Fields.Name") directly on the form renders the correct language so Umbraco isn't caching the whole view.

warrenbuckley commented 9 years ago

Hi All, I will try to spend sometime at lunch today to get to the bottom of this and see what is happening and compare what is happening

craigacronin commented 9 years ago

Thanks Warren

It would be really great to see the package incorporated into the core product in the future.

Craig

From: Warren Buckley [mailto:notifications@github.com] Sent: 29 January 2015 09:39 To: warrenbuckley/Umbraco-Validation-Attributes Cc: Craig Cronin Subject: Re: [Umbraco-Validation-Attributes] Umbraco Validation Attributes plugin fails to load dictionary values in Umbraco v7.1.9 + (#25)

Hi All, I will try to spend sometime at lunch today to get to the bottom of this and see what is happening and compare what is happening

— Reply to this email directly or view it on GitHub https://github.com/warrenbuckley/Umbraco-Validation-Attributes/issues/25#issuecomment-71995151 .

chris64digital commented 9 years ago

Is there any news on this? I agree that this should be in the core product. Seems like a pretty basic function for a multi-language cms!

warrenbuckley commented 9 years ago

Sorry as always life & other stuff gets in the way. I won't promise a timeframe for this but it's on my list of personal dev stuff to do/look at.

craigacronin commented 9 years ago

Thanks warren

I have a workaround now but your solution was nicer and structured better :)

Sent from my iPhone

On 6 Feb 2015, at 09:28, Warren Buckley notifications@github.com wrote:

Sorry as always life & other stuff gets in the way. I won't promise a timeframe for this but it's on my list of personal dev stuff to do/look at.

— Reply to this email directly or view it on GitHub.

craigacronin commented 9 years ago

Hi Chris, just wondering if you managed any workarounds? I'm just moving back to our new corporate website and need this functionality. I think i came across a solution previously but just not as nice.

chris64digital commented 9 years ago

Hi Craig,

Unfortunately we decided that the alternative language versions of the validation messages weren't important enough to spend time on for this particular site! If our client decides otherwise in the future I will update the thread.

Chris

On Thu, Mar 12, 2015 at 3:06 PM, Craig Cronin notifications@github.com wrote:

Hi Chris, just wondering if you managed any workarounds? I'm just moving back to our new corporate website and need this functionality. I think i came across a solution previously but just not as nice.

— Reply to this email directly or view it on GitHub https://github.com/warrenbuckley/Umbraco-Validation-Attributes/issues/25#issuecomment-78498243 .

Chris Foot Web Developer

Support 0800 634 5792 Sales 0800 564 2253 Fax 01296 340 201

1st Floor, 34 Market Square, Aylesbury, Bucks, HP20 1TW

www.64digital.co.uk Company Reg: 5131222 VAT No: 841555036

craigacronin commented 9 years ago

Hi. I'm back to this problem as part of my corporate build. Has anyone got a solution for this?

Thanks

craigacronin commented 9 years ago

I've fixed this issue...I think. I going to implement what I've done on my current build this afternoon but will create a pull request next week with my changes. I've looked at various solutions to this problem and this library looks to be the most comprehensive and most flexible really so its good to have it working.

I'm about 80% of the way through fixing attributes at the moment.

mkariti commented 9 years ago

Hi craigcronin, Did you managed to crack this one? Regards, mkariti

craigacronin commented 9 years ago

Hi mkariti

Yes I have. I've got about 80% of the main attributes working and was going to finish the rest Monday/Tuesday and make a pull request.

If you need it sooner I can email it over Monday morning when I get back to work

Sent from my iPhone

On 23 Apr 2015, at 19:36, mkariti notifications@github.com wrote:

Hi craigcronin, Did you managed to crack this one? Regards, mkariti

— Reply to this email directly or view it on GitHub.

mkariti commented 9 years ago

Hi craigacronin, Many thanks for your reply. Will be great if you can email it to me. You can use my public email address. Regards, mkariti

J35P1N commented 9 years ago

Has anyone managed to get this working on the latest versions of Umbraco? It is kind of vital that we are able to use dictionary values to pull out multi-language error messages for our end users. Any help would be greatly appreciated.

craigacronin commented 9 years ago

Hi Jason

Yes I have but the code is in work. How urgent is it?

Sent from my iPhone

On 1 May 2015, at 17:42, Jason Espin notifications@github.com wrote:

Has anyone managed to get this working on the latest versions of Umbraco? It is kind of vital that we are able to use dictionary values to pull out multi-language error messages for our end users. Any help would be greatly appreciated.

— Reply to this email directly or view it on GitHub.

warrenbuckley commented 9 years ago

@craigacronin I look forward to the pull request

craigacronin commented 9 years ago

Sorry for the delay.

I've been on first aid training for 3 days last week and just caching up with things.

Will do Tuesday morning.

Sent from my iPhone

On 2 May 2015, at 09:04, Warren Buckley notifications@github.com wrote:

@craigacronin I look forward to the pull request

— Reply to this email directly or view it on GitHub.

warrenbuckley commented 9 years ago

@craigacronin will you be submitting this soon?

craigacronin commented 9 years ago

Hi warren

Will do it when I get back from lunch

Sent from my iPhone

On 6 May 2015, at 13:07, Warren Buckley notifications@github.com wrote:

@craigacronin will you be submitting this soon?

— Reply to this email directly or view it on GitHub.

J35P1N commented 9 years ago

This is still not working for me. I have tried it on version 7.2.4 and no joy. It seems to completely ignore the UmbracoValidationAttributes data annotations.

I've tried adding this into my project as a reference as well as adding the files directly into my project in the App_Code folder and still no joy.

More details here:

https://our.umbraco.org/forum/developers/razor/64191-Umbraco-Validation-Attributes