if I need to decorate the name of the parameter for a nested resource do I need to create a Custom filter or there is a simple way to do so?
#[ApiFilter(SearchFilter::class, properties: ['partnerRestrictionTag.value' => 'exact'])]
I would like to have this parameter as
api/partnerRestriction?restriction=test
and not
api/partnerRestriction?partnerRestrictionTag.value=test
Related
How can I display Date Humanizely inside DisplayFor?
I tried like this : #Html.DisplayFor(model =>model.EndDate.Humanize())
but editor shows error like:
an expression tree may not contain a call or invocation that uses
optional arguments
Html.DisplayFor is a templated helper, which just means it returns the value of the model expression using a template. The default template is simply calling ToString() on the property referenced by the model expression. As such, what you pass into it must be a model expression referencing a particular property; you cannot do something like call Humanize on it.
However, you can define your own template. This entails creating a view in Views\Shared\DisplayTemplates, which conforms to one of these naming conventions:
It's named after the type it should be used for, e.g. DateTime.cshtml will be applied to any property that is of type DateTime.
It's named after one of the members of the DataType enum, in which case, it's utilized when that DataType is applied to a particular property, e.g. Date.cshtml will be utilized when you apply the attribute [DataType(DataType.Date)].
It's named whatever you like, but that name is explicitly specified for the property using the UIHint attribute, e.g. if you apply an attribute like [UIHint("MyAwesomeDateTime")] and associated MyAwesomeDateTime.cshtml view will be used.
As such, if you were to create a view like Views\Shared\DisplayTemplates\DateTime.cshtml with the contents:
#model DateTime
#Model.Humanize()
Then, simply calling #Html.DisplayFor(m => m.EndDate) will return the humanized date you're looking for. Since EndDate is a DateTime, DisplayFor will utilize your DateTime.cshtml template, which outputs the model (your DateTime with Humanized chained.
An alternative way to specify a display template is to pass it in directly. This is useful when you have a one-off situation and you don't want the template to apply to everything of a particular type. For example, if you just wanted EndDate humanized, but other dates to display as normal, that could be achieved by doing something like:
#Html.DisplayFor(m => m.EndDate, "HumanizedDate")
You would then of course need an associated HumanizedDate.cshtml. You can also employ UIHint on your property as described above here, if you'd prefer to keep this out of the view, and on your model instead.
All that said, display templates are best utilized when there's complex constructions involved. As Stephen pointed out in the comments below your question, you could easily just do: #Model.EndDate.Humanize(), which not only is more terse and explicit than #Html.DisplayFor(m => m.EndDate), but also doesn't require adding custom views or attributes to your model properties.
Is there a way to use a custom Object with the #Field annotations and parse the field entries from the object? Also, is there a way to use some sort of constant field?
I found that I could use #FieldMap and provide an object implementing Map. I personally just extended HashMap and set the fields in the constructor...
I would like to customize at runtime the attributes that MVC sees on a view model property. As far as I know, MVC relies internally on type descriptors to enumerate the attributes. Is there a way to hook a type descriptor somewhere to return a custom list of attributes for a property?
Is there a way to hook a type descriptor somewhere to return a custom
list of attributes for a property?
It depends. If you want to override the Data Annotations used by the metadata provider then you could write your own custom ModelMetadataProvider and replace the default one (DataAnnotationsModelMetadataProvider). This allows you to have a custom metadata provider for a given type and return this information at runtime.
If on the other hand you are doing validation, then you are a bit out of luck. For more flexibility I would recommend you using FluentValidation.NET instead of data annotations.
I am not able to get how to pass a parameter along with a main url from a controller. I tried like this:
return new ModelAndView(new RedirectView("home?var=ss", true));
But I am getting null value for var . What is the correct way?
The documentation says:
By default all model attributes are considered to be exposed as URI
template variables in the redirect URL. Of the remaining attributes
those that are primitive types or collections/arrays of primitive
types are automatically appended as query parameters.
So you don't have anything to do except making sure that you have a model attribute named var, with the value ss.
I am having issues with twig escaping output on method calls to an object passed into my twig template. I know I can get around this with the |raw filter, but was hoping there might be a way I could simply specify in my object that certain methods are safe and therefore remove the need for the raw filter.
Method calls of objects itself cannot be made html safe because normal objects/entities are not (and should not be) aware of the template engine.
However, a twig filter or function if aware of the template engine and can be marked html safe in its definition.
So what you need to do is to implement a html safe twig filter to pass the object to and call the method of your object inside the filter function.
I guess your templates looks like this:
<p>{{myObj.getHtmlRepresentation()|raw}}</p>
Now you need to implement a twig filter and change the template to the following:
<p>{{myObj|html_representation}}</p>
And the twig extension should look like this:
class MyTwigExtension {
public function getFilters(){
return array(
// the magic is the is_safe=>html option
'html_representation' => new \Twig_Filter_Method($this,'htmlRepresentation',array('is_safe'=>array('html'))),
}
public function htmlRepresentation($obj){
return $obj->getHtmlRepresentation();
}
}
One design consideration: If your object is an entity of a business object of some kind, it sould not create html but you should move the html creation to a template or the twig filter..