In my controller there is a method take accepts one route and and one query parameter as arguments:
/// <summary>
/// My Method
/// </summary>
/// <param name="routeParameter">Nice description of route parameter.</param>
/// <param name="queryParameter">Nice description of query paramter.</param>
[HttpPost("somePath/{routeParameter}")]
public IActionResult MyMethod([FromRoute] string routeParameter, [FromQuery] DateTime queryParamter)
{
// do something
}
In the OpenApi.json / Swagger generated from this signature via Swashbuckle XML the routeParameter (path) is always required but the queryParameter (query) is marked as optional.
How can I mark the query parameter as required, too?
How can I mark the query parameter as required, too?
Just use [FromQuery, BindRequired] as follow:
[HttpPost("somePath/{routeParameter}")]
public IActionResult MyMethod([FromRoute] string routeParameter, [FromQuery, BindRequired] DateTime queryParamter)
{
// do something
}
Here is the test result:
Here is an alternative with [FromUri] to receive your parameters
[HttpPost("somePath")]
public IActionResult MyMethod([FromUri] Paging paging, [FromUri] QueryParam param)
{
// do something
}
QueryParam.cs
public class QueryParam
{
[Required]
public string routeParameter{ get; set; }
}
Swagger UI
Related
I would like wrap my web api controller response in a generic class and can't work out how to get the actual type from HttpResponseMessage.Content.
e.g. My Controller
[ResponseType(typeof(ApiAuthentication))]
public IHttpActionResult PostLogOnTest()
{
ApiAuthentication loginResponse = new ApiAuthentication();
return Ok(loginResponse);
}
I need to be able to wrap all the controller response in a 'data' container. I could code this response class into each method but I thought it would be nice to do in common place? So I have a class
[DataContract]
public class ApiResponse<T>
{
/// <summary>
/// Gets or sets the data.
/// </summary>
/// <value>
/// The data.
/// </value>
[DataMember(Name="data")]
public T Data { get; set; }
}
I can hook into a MessageHandler and get the HttpResponseMessage but when I try to get the Content from .Content - it comes as a ObjectContent<> - i just want the ApiAuthentication so i can then create new HttpResponseMessage>
Is there any way to do this or easier way?
Thanks
Recently i've start playing with new web api help page functionality, that was recently added to web api project template. And i have a notice that some "Additional information" column is always 'none'.
After some looking at markup i found that this info should arrive from attributes
<td class="parameter-annotations">
#if (parameter.Annotations.Count > 0)
{
foreach (var annotation in parameter.Annotations)
{
<p>#annotation.Documentation</p>
}
}
else
{
<p>None.</p>
}
</td>
But what kind of attribute i should use, to populate additional information?
Thanks
See this site for an example of how to add additional information.
It's basically annotating your model, so in your case it would be something like:-
public class Product
{
/// <summary>
/// The id of the product
/// </summary>
[Required]
public int Id { get; set; }
/// <summary>
/// The name of the product
/// </summary>
[MaxLength(50)]
public string Name { get; set; }
}
Which would give you an output like this:-
I have a ASP.NET Web API which returns a template class but I can't get the Web API Help Page to provide documentation for the return type correctly.
Let's say I have the following Model classes:
public class MyType<T>
{
/// <summary>A list of T</summary>
public List<T> MyList { get; set; }
}
public class Foo
{
/// <summary>Bar string</summary>
public string Bar { get; set; }
}
and my API action looks as follows
[ResponseType(typeof(MyType<Foo>))]
public IHttpActionResult Get()
{
return Ok<MyType<Foo>>(new MyType<Foo>());
}
The resulting Web API Help Page then declares that the Get action returns a MyTypeOfFoo and do not provide the XML documentation for MyType, it just lists the parameters it contains. Probably because it don't understand that MyTypeOfFoo is the same as MyType<Foo>.
Are there any known solutions to this problem?
Update
Creating a pseudo-class and returning it instead does not work either. E.g.
/// <summary>My Foo Type</summary>
public class MyFooType : MyType<Foo>
{
}
[ResponseType(typeof(MyFooType)]
public IHttpActionResult Get()
{
return Ok<MyFooType>(new MyFooType());
}
The documentation output for the above code lacks the comments available on the inherited properties.
I'm using a generic return type for all my api responses:
public HttpStatusCode statusCode { get; set; }
public string error { get; set; }
public IDictionary<string, string> errorfor { get; set; }
public T result { get; set; }
and in API:
/// <summary>
/// GET Order API
/// </summary>
/// <returns> return list of orders {Order} </returns>
public HttpResponseMessage Get(){
var response = new BaseResponseMessage<IList<Order>>();
//some more codes
response.result = orders;
return Request.CreateResponse(HttpStatusCode.OK, response);
}
Now of course my API Help page don't show Order in sample Response body. Is it possible to configure Help Page generator to show generic type? Thanks!
Web API 2.1 Help Pages now do this: http://www.asp.net/web-api/overview/releases/whats-new-in-aspnet-web-api-21#help-page
You might also check out returning the standard HttpResponseMessage with the new ResponseTypeAttribute:
/// <summary>
/// GET Order API
/// </summary>
[ResponseType(typeof(List<Order>))]
public HttpResponseMessage Get()
{
var orders = new List<Order>();
return Request.CreateResponse(HttpStatusCode.OK, orders);
}
It would not be possible for HelpPage to guess what would be the return type of an action with just the signature that you have. As you know HelpPage generation does not happen during normal request, but is something which depends on static information.
There is a workaround for this though. You can look at the following commented code in Areas\HelpPage\App_Start\HelpPageConfig.cs which lets you specify a specific return type for an action.
//// Uncomment the following to correct the sample response when the action returns an HttpResponseMessage with ObjectContent<string>.
//// The sample will be generated as if the controller named "Values" and action named "Post" were returning a string.
//config.SetActualResponseType(typeof(string), "Values", "Post");
I understand that this workaround would be too cumbersome for you since you mentioned about having this kind of signature for all your actions.
You could probably extend HelpPage by creating a custom attribute which informs about the return type and decorate it on the actions. You can then modify installed HelpPage code to look for these attributes.
I have begun to test Fluent NHibernate in C#
I have a well normalized object structure with 20 related classes.
I currently use Fluent 1.3 with NHibernate 3.2.
So far I have managed to use the AutoMap feature which suits me fine,
Very convenient!
BUT ...
3 of the tables are "enum tables" that need to have their records set with specific Id value.
I tried to make manual mappings of these tables and let the rest be automapped.
But when the manual table is created it fails because it references a table that is automapped (and not available for manual mapper?)
Is it possible to use AutoMapping but for some very few classes override identity creation on primary key?
I tried to make a custom convention but without success.
public class OverrideIdentityGeneration : Attribute
{
}
public class ConventionIdentity : AttributePropertyConvention<OverrideIdentityGeneration>
{
protected override void Apply(OverrideIdentityGeneration attribute, IPropertyInstance instance)
{
instance.Generated.Never();
}
}
Is there some other way?
It would be sad to be forced back to use manual mapping for all classes ....
class MyIdConvention : IIdConvention
{
public void Apply(IIdentityInstance instance)
{
if (instance.EntityType == ...)
{
instance.GeneratedBy.Assigned();
}
}
}
Update:
for enum-like classes it's often easier to define an enum as id
class ConfigValue
{
public virtual Config Id { get; set; }
}
// the convention is easy
if (instance.EntityType.IsEnum)
{
instance.GeneratedBy.Assigned();
// to save as int and not string
instance.CustomType(typeof(Config));
}
// querying without magic int values
var configValue = Session.Get<ConfigValue>(Config.UIColor);
I used the idea given by Fifo and extended it to use a custom attribute instead.
To make code readable and avoid redundance when using similar idea in other conventions I added an extension method to check for custom attribute.
This is the code I ended up with:
/// <summary>
/// Convention to instruct FluentNHIbernate to NOT generate identity columns
/// when custom attribute is set.
/// </summary>
public class ConventionIdentity : IIdConvention
{
public void Apply(IIdentityInstance instance)
{
if(instance.CustomAttributeIsSet<NoIdentity>())
instance.GeneratedBy.Assigned();
}
}
/// <summary>
/// Custom attribute definition.
/// </summary>
public class NoIdentity : Attribute
{
}
/// <summary>
/// Example on how to set attribute.
/// </summary>
public class Category
{
[NoIdentity]
public int Id { get; set; }
public string Name { get; set; }
}
public static class IInspectorExtender
{
/// <summary>
/// Extender to make convention usage easier.
/// </summary>
public static T GetCustomAttribute<T>(this IInspector instance)
{
var memberInfos = instance.EntityType.GetMember(instance.StringIdentifierForModel);
if(memberInfos.Length > 0)
{
var customAttributes = memberInfos[0].GetCustomAttributes(false);
return customAttributes.OfType<T>().FirstOrDefault();
}
return default(T);
}
}