2008-10-24 8 views

Antwort

12

Wenn Sie versuchen, diese Methode zu erweitern:

public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues); 

Obwohl ich sicher, dass Objekt-Erweiterungen des Khaja bin funktionieren würde, könnte man eine bessere Leistung erhalten, indem eine Routevaluedictionary Erstellung und Weitergabe in der Routevalues ​​Objekt Ihre weitere Parameter aus dem Kontext hinzufügen, dann wieder die Action Überlastung verwenden, die eine Routevaluedictionary anstelle eines Objekts nimmt:

Dieser den Trick tun sollten:

public static MvcHtmlString MyLink(this HtmlHelper helper, string linkText, string actionName, object routeValues) 
    { 
     RouteValueDictionary routeValueDictionary = new RouteValueDictionary(routeValues); 

     // Add more parameters 
     foreach (string parameter in helper.ViewContext.RequestContext.HttpContext.Request.QueryString.AllKeys) 
     { 
      routeValueDictionary.Add(parameter, helper.ViewContext.RequestContext.HttpContext.Request.QueryString[parameter]); 
     } 

     return helper.ActionLink(linkText, actionName, routeValueDictionary); 
    } 
+0

Funktioniert wie ein Charme, dies sollte die akzeptierte Antwort sein! BTW: Wenn Sie die Objektüberladungen von ActionLink() bisher verwenden, müssen Sie htmlAttributes mit HtmlHelper.AnonymousObjectToHtmlAttributes (htmlAttributes) umbrechen, um die korrekte Überladung aufzurufen! –

39

Ich nehme an, Sie meinen hier anonyme Typen, z.B. new { Name1=value1, Name2=value2} usw. Wenn ja, hast du kein Glück - anonyme Typen sind normale Typen, da sie fester, kompilierter Code sind. Sie werden zufällig automatisch generiert.

Was Sie könnte tun ist new { old.Name1, old.Name2, ID=myId } schreiben, aber ich weiß nicht, ob das wirklich das ist, was Sie wollen. Einige weitere Details zur Situation (einschließlich Codebeispielen) wären ideal.

Alternativ könnten Sie ein Container-Objekt erstellen, das immer hatte eine ID und was auch immer anderes Objekt enthielt den Rest der Eigenschaften.

0
public static string TextBox(this HtmlHelper html, string value, string labelText, string textBoxId, object textBoxHtmlAttributes, object labelHtmlAttributes){} 

Dies würde den ID-Wert akzeptieren, den die Textbox haben sollte und auf den das Etikett verweisen sollte. Wenn der Consumer jetzt die Eigenschaft "id" nicht in textBoxHtmlAttributes enthält, erstellt die Methode eine falsche Bezeichnung.

Ich kann durch Reflexion überprüfen, wenn dieses Attribut im labelHtmlAttributes-Objekt hinzugefügt wird. Wenn ja, möchte ich es hinzufügen oder ein neues anonymes Objekt erstellen, das hinzugefügt wurde. Aber weil ich keinen neuen anonymen Typ erstellen kann, indem ich die alten Attribute durchlaufe und mein eigenes "id" -Attribut hinzufüge, stehe ich irgendwie fest.

Ein Container mit einer stark typisierten ID-Eigenschaft und einer anonymen typisierten "attributes" -Eigenschaft würde Code-Umschreibungen erfordern, die nicht die Anforderung "Id-Feld hinzufügen" erfüllen.

Hoffe, diese Antwort ist verständlich. Es ist das Ende des Tages, kann meine Gehirne in Linie nicht mehr bekommen ..

+0

Nun ... Sie * könnten * einen neuen Typ (mit CodeDOM usw.) erstellen, der die relevanten Eigenschaften enthielt. Aber der Code wäre hässlich. Kann ich vorschlagen, statt ein Objekt zu nehmen und die Eigenschaften durch Reflexion zu betrachten, ein IDictionary oder etwas? (Fortsetzung) –

+0

Sie könnten dieses Wörterbuch mit einer Hilfsmethode aufbauen, die das ganze Reflektions-Ding gemacht hat - und möglicherweise eine Wrapper-Methode hat, die genau das tat - aber ein Wörterbuch klingt, als wäre es näher an dem, was Sie wirklich darstellen wollen; anonyme Objektinitialisierer sind nur syntaktisch praktisch. –

68

Die folgende Erweiterungsklasse würde Sie bekommen, was Sie brauchen.

public static class ObjectExtensions 
{ 
    public static IDictionary<string, object> AddProperty(this object obj, string name, object value) 
    { 
     var dictionary = obj.ToDictionary(); 
     dictionary.Add(name, value); 
     return dictionary; 
    } 

    // helper 
    public static IDictionary<string, object> ToDictionary(this object obj) 
    { 
     IDictionary<string, object> result = new Dictionary<string, object>(); 
     PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(obj); 
     foreach (PropertyDescriptor property in properties){ 
      result.Add(property.Name, property.GetValue(obj)); 
     } 
     return result; 
    } 
} 
+2

100% richtig.Obwohl Sie normalerweise anonyme Typen für HTML-Attribute verwenden, ist es eigentlich ein IDictionary und Sie können daher leicht hinzufügen/entfernen. –

+9

http://msdn.microsoft.com/en-us/library/system.web.mvc.htmlhelper.anonymousobjecttohtlattributes(v=vs.108).aspx tut das gleiche, aber es ist in System.Web.Mvc eingebaut. HtmlHelper. – Mir

+1

Warum ist ToDictionary öffentlich und nicht privat, macht es keinen Sinn, diese Methode zu veröffentlichen? –