web-dev-qa-db-fra.com

ASP.NET MVC Editor-Modèles / Uihint avec Paramètres

J'utilise des modèles de rédaction dans le passé comme celui-ci, en appliquant l'annotation de données suivante:

[UIHint("SomeTemplate")]

ViewModel :

 public class MicroViewModel
 {
    public IEnumerable<LabMicro> Micros { get; set; }

    [UIHint("DateTime")]
    public DateTime Date { get; set; }

    public int CaseNo { get; set; }

    [UIHint("SampleTypes")]
    public int LabSampleTypeID { get; set; }

    [UIHint("SampleDetails")]
    public int LabSampleDetailID { get; set; }
 }

Si je voulais utiliser un contrôle de sélecteur de date spécifique, par opposition au régulier, il peut être mis en œuvre comme suit.

Exemple :

@model DateTime?    
@Html.TextBox("",  String.Format("{0:yyyy-MM-dd}", Model.HasValue ? 
        Model : DateTime.Today), new { @class = "dp", style="width:100px" })

<script type="text/javascript">    
    $(document).ready(function () {    
        $(".dp").datepicker({    
            changeMonth: true,    
            changeYear: true,
            dateFormat: 'yy-mm-dd'    
        });    
    });      
</script>  

Pour mes champs d'identité, je voudrais utiliser la composante auto-complète JQuery.

Question :

Comment puis-je continuer à passer des paramètres supplémentaires à la vue UIHint partielle pour LabSampleTypeID et LabSampleDetailID? (comme ID aime avoir un modèle d'éditeur automatique complet qui prendra une URL et des noms de propriété par exemple)

Ce que je pense que mon modèle de rédaction automatique/partiel doit ressembler à :

$(".auto").autocomplete({
    source: function(request, response) {
        $.ajax({
            url: '[#URL_TO_USE]',
            dataType: "json",
            data: {
                filter: request.term
            },
            success: function(data) {
                response($.map(eval(data), function(item) {
                    return {
                        label: item.[#PROPERTY_TO_USE]
                    }
                }));
            }
        })
    }
});
40
Rohan Büchner

Vous pouvez utiliser l'attribut AdditionalMetadata:

[UIHint("DateTime")]
[AdditionalMetadata("foo", "bar")]
public DateTime Date { get; set; }

et dans le modèle:

@ViewData.ModelMetadata.AdditionalValues["foo"]

donc, si vous vouliez passer une URL:

[UIHint("DateTime")]
[AdditionalMetadata("controller", "somecontroller")]
[AdditionalMetadata("action", "someaction")]
[AdditionalMetadata("property", "someproperty")]
public DateTime Date { get; set; }

et dans votre modèle:

@{
    var values = ViewData.ModelMetadata.AdditionalValues;
}

<script type="text/javascript">
$('.auto').autocomplete({
    source: function (request, response) {
        $.ajax({
            url: '@Url.Action((string)values["action"], (string)values["controller"])',
            dataType: "json",
            data: {
                filter: request.term
            },
            success: function (data) {
                response(
                    $.map(eval(data), function (item) {
                        return {
                            label: item['@values["property"]']
                        }
                    })
                );
            }
        });
    }                    
});
</script>
75
Darin Dimitrov

Vous pouvez utiliser l'UHINT sans attribut supplémentaire supplémentaire, mais un code supplémentaire est requis

[UIHint("DateTime", null, "key1", "value1", "key2", "value2")]
public DateTime Date { get; set; }

remplacer CreatemetaData:

public class CustomMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        public const string UiHintControlParameters = "UiHintControlParameters";

        protected override ModelMetadata CreateMetadata(
            IEnumerable<Attribute> attributes,
            Type containerType,
            Func<object> modelAccessor,
            Type modelType,
            string propertyName)
        {

            ModelMetadata metadata = base.CreateMetadata(
                attributes,
                containerType,
                modelAccessor,
                modelType,
                propertyName);

            IEnumerable<UIHintAttribute> uiHintAttributes = attributes.OfType<UIHintAttribute>();
            UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => string.Equals(a.PresentationLayer, "MVC", StringComparison.OrdinalIgnoreCase))
                                              ?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer));
            if (uiHintAttribute != null)
            {
                metadata.AdditionalValues.Add(UiHintControlParameters, uiHintAttribute.ControlParameters);
            }

            return metadata;
        }

Inscrivez-vous CustMeTataProvider:

    public static void Application_Start()
    {
        ModelMetadataProviders.Current = new CustomMetadataProvider();
    }

et dans votre modèle:

    @{
        IDictionary<string, object> values = (IDictionary<string, object>)
ViewData.ModelMetadata.AdditionalValues[CustomMetadataProvider.UiHintControlParameters];
    }
4
Sel