Breeze Server Side验证和资源转换

时间:2014-07-02 21:51:26

标签: breeze

我正在研究使用模型验证与Breeze,我发现它在添加例如[Required]时确实有效,但错误消息似乎来自Breeze本身,我希望它能直接提取消息来自模型,但事实并非如此。我必须用资源翻译(英语,法语,西班牙语)构建我的下一个项目,我宁愿让Breeze Controller以某种方式直接获取错误消息。举个例子,在我之前的项目中,我有一个模型:

[Display(ResourceType = typeof(Resources.Validations), Name = "SiteName")]
[Required(ErrorMessageResourceType = typeof(Resources.Validations), ErrorMessageResourceName = "Required")]
public string siteName { get; set; }

第一个注释Display将改变我输入的名称,我将在Angular中处理那个,所以我们可以跳过那一个,但我想要第二个注释Required(ErrorMessageResourceType = ...)] ,我宁愿让Breeze独自完成...有了更多的解释,在我的资源文件中,我用英语翻译Required翻译The {0} field is required.以及我看到的实际错误消息在Breeze里面是'%displayName%' is required.,所以我马上就可以看到它没有从模型中提取任何资源文件,而是内置的Breeze错误消息。我从这个Breeze Server-side validation page找到了一些信息,它确实谈到了自定义验证器,但我认为这实际上应该是内置的,不是吗?有没有办法让它们自动填充?哦,为了提供一些关于我自己的项目的信息,我在ASP MVC5中使用Breeze和WebApi控制器,并且使用EF6和Breeze.ContextProvider.EF6。 Breeze是否可以从模型中获取所有模型数据注释,或者它是否实现了有限的集合?从这个微风页面Add a Breeze validator,我看到了其中几个,但我不确定它是否只是客户端。

我也发现了这个问题/答案Translate breeze validation messages,但这似乎是客户端,我宁愿让Breeze自动从我的模型中提供的资源中获取翻译。

如果你提供了答案,请包括代码示例,我总是更直观......谢谢:)

1 个答案:

答案 0 :(得分:1)

所以我没有任何答案,我将回复我到目前为止所发现的内容......虽然我已提交{但此时尚未支持Breeze支持资源翻译的答案{3}}

要做翻译,我必须先在我的EMFactory中启动微风时翻译Breeze Validators,我发现的方式是:

function emFactory($cookies, breeze, fileService) {
    var lang = $cookies.lang || "en";

    // load the validator templates translation mapping (external files: validators.{lang}.json)
    var translations = loadValidatorsTranslation();
    breeze.Validator.messageTemplates = translations[lang];

    // Identify the endpoint for the remote data service
    var serviceRoot = window.location.protocol + '//' + window.location.host + '/';
    var serviceName = serviceRoot + 'breeze/BreezeApi';

    var factory = {
        newManager: function () { return new breeze.EntityManager(serviceName); },
        serviceName: serviceName,
        language: lang
    };

    return factory;
}

function loadValidatorsTranslation() {
    return {
        en: {
            // ...
            required: "'%displayName%' is required",
            string: "'%displayName%' must be a string",
            stringLength: "'%displayName%' must be a string with between %minLength% and %maxLength% characters",
            url: "The %displayName% '%value%' is not a valid url"
        },
        fr: {
            // ...
            required: "'%displayName%' est requis",
            string: "'%displayName%' doit être une chaîne de caractère",
            stringLength: "'%displayName%' doit être une chaîne de caractère entre %minLength% et %maxLength% caractères",
            url: "%displayName% '%value%' n'est pas un URL valide"
        }
    };
}

然后我创建了一个TranslationService来处理我的Breeze上下文的displayNames实体:

appDemo.factory('translationService', ['$q', '$timeout', translationService]);

function translationService($q, $timeout) {
    // declare the displayNames translations of entities
    var displayMapping = {
        fr: {
            City: {
                Name: "Nom de Ville"
            },
            Speaker: {
                Bio: "Bio",
                Image: "Image",
                Name: "Nom du Conférencier"
            }
        },
        en: {
            City: {
                Name: "City Name"
            },
            Speaker: {
                Bio: "Bio",
                Image: "Image",
                Name: "Speaker Name"
            }
        }
    };

    // reveal the public functions & return the service 
    return {
        loadTranslationDisplayNames: loadTranslationDisplayNames
    };


    // -- public functions 
    // --------------------
    function loadTranslationDisplayNames(manager, lang, entityTypes) {        
        for (var i = 0, ln = entityTypes.length; i < ln; i++) {
            // get the specific context Entity
            var custType = manager.metadataStore.getEntityType(entityTypes[i]);
            var entityProperties = displayMapping[lang][entityTypes[i]];
            // loop through all properties of this Entity and update their DisplayName
            for (var name in entityProperties) {
                custType.getProperty(name).displayName = entityProperties[name];
            }
        }
    }
}

最后在我的DataService中,我用这个

来调用我的TranslationService
function dataService($rootScope, $q, breeze, entityManagerFactory, translationService) {
    var service = this;

    // reveal the public functions we want, any other functions will remain private
    service.getSpeakers = getSpeakers;

    var manager = entityManagerFactory.newManager();
    var lang = entityManagerFactory.language;

    return service;

    // -- public/private functions declaration
    function getSpeakers() {
        var query = new breeze.EntityQuery.from("Speakers");

        // load the translation of Breeze DisplayNames entities
        translationService.loadTranslationDisplayNames(manager, lang, ["City", "Speaker"]);

        startProcessingData();

        var promise =
            manager.executeQuery(query)
                   .catch(queryFailed)
                   .finally(processingDataComplete);

        return promise;
    }
}

...所以这项工作,我只需要随时使用我的新翻译更新我的TranslationService。如果其他人有更好/更清洁的解决方案,我很乐意看到它......