How do I publish the ASP.NET Web API model class definition? - c#

I'm trying to understand how or what options are available for publishing the model class that is passed to my ASP.NET Web API CRUD methods. Here is an example of my POST method.
public HttpResponseMessage PostMaterial(Material material)
{
try
{
repository.Add(material);
}
catch (ArgumentNullException)
{
var exceptionResponse = Request.CreateResponse("Material object was null.");
return exceptionResponse;
}
var response = Request.CreateResponse("Material " + material.MaterialName + " created.");
string uri = Url.Link("DefaultApi", new { materialName = material.MaterialName });
response.Headers.Location = new Uri(uri);
return response;
}
In this example a material object is passed as a parameter when the method is called by an external API user. That caller would need a definition of the material class, so then could correctly build the object they will need to pass. If anyone has some details or a better explanation, then please let me know. I haven't had much luck finding an answer which leads me to believe I'm asking the wrong question.

I had the same situation and had two approaches:
Approach 1:
Use help pages for web API
Approach 2:
I can create a simple GET method which returns my model(blank or default values) in response. so they (caller) will know that what parameters/objects needs to send to consume the web api in their application.(but for this also i need to inform them about that method :) )
So, I choose the first approach as it is really helpful for external application developer to understand your web api properly. You can properly document your API also by using Web API help pages.

Related

Getting the response from Web Api using Angular Controller

I am just trying to figure out what would be the easiest and quickest way to get particular value from WebApi controller.
my web API controller
public IEnumerable<string> Get()
{
return new string[] { fullname,lastname, email};
}
when I try to consume this web API in the angular controller by using the below method
this._httpService.get('/api/user').subscribe(values => {
this.details= values.json() as string[];
});
it returns all the values (fullname,lastname, email). but what I am trying to get here is lastname.
something like this.details.lastname
For clarity, if you are using Angular (not AngularJS), then the code is called a component not a controller.
Which version of Angular are you using? If it is > 4.3, then you don't need the .json() anymore. The mapping is handled for you automatically.
To answer your question ... the "quickest" way would be something like this (assuming Angular v6):
this.http.get<>('/api/user').subscribe(
details => this.lastName = details.lastName
);
Assuming that details is one item, not an array.
But this is definitely not the "best" way.
The best way would be to define an interface for your details and then build a proper client-side service to encapsulate your data access.

Creating filter in WebApi2 to filter Images

I a newbie to webapi and have created a web api project. Different controller method here needs image as parameter. I am using an external 3rd party api to check if the image uploaded by the users is not any profane image. So instead of checking it at actionMethod level ,i thought it might be a good idea to check using a filter that way it will save me time of checking it individually. But i haven't got a clue as to how to start writing the code for this.
public class ImageFilter : FilterAttribute,IFilter
{
public void OnActionExecuting(HttpActionContext httpActionContex)
{
if(!httpActionContex.ActionDescriptor.) // ???? what should come
}
}
please guide me. Don't need the exact code just the correct direction and guidance .. thanks
A FilterAttribute is, as its name implies, an attribute that can be set globally on the WebAPI pipeline, or individually on a specific controller method. You can simply slap the [ImageFilter] attribute on your specific controller method, and the WebAPI pipeline will execute the filter before executing the action method - giving you a chance to filter what requests make it to the method.
For the actual implementation of your custom logic, you can access the HttpContext.Current.Request in your OnActionExecuting method, allowing you to access the incoming HTTP request. You can then read the data from it, pass it to your 3rd party API, and if it doesn't pass the filter, you can access the Response and end it before it even reaches the controller:
var response = HttpContext.Current.Response;
response.StatusCode = (int)HttpStatusCode.BadRequest; // or whatever
response.End();

Web Api documentation based on type of the content in HttpResponseMessage

I'm building a WebApi and I want to create documentationfor it.
Most of my methods should return data in format:{errorCode:200, errorMessage:'msg', data:[item1{}, item2{}, ...]}.
So I've created a class 'ResponseDTO' for it and added a summary. If in the controller method I return: return new ResponseDTO(201, "Test", someData); ASP.NET will create a good standart documentation for me.
But actually I want to return something like this: return Request.CreateResponse<ResponseDTO>(HttpStatusCode.OK, response);. In this case ASP.Net creates a documentation about HttpResponseMessage.
Can I make ASP.Net create the documentation about the type which I specify in CreateResponse<T>?
I've found exactly what I was looking for: [ResponseType(typeof(ResponseDTO))]
Thanks for: http://www.strathweb.com/

Web API 2.2 return custom 404 when resource (url) not found

I want to be able to take over the 404 response from web api (iis) when the resource does not exist.
I have done my research and came across only one solution that made this work, but i am not sure how "safe" it is since the "routeTemplate" is just {*url}
This post is kinda to ask for help and explanation.
My App uses MVC and WebAPI... would this template affect MVC as well?
Is there a way to add "api" with {*url} in the template? (to make sure only requests with ".../api/..." get affected)
config.Routes.MapHttpRoute("Error404", "{*url}", new { controller = "Error", action = "Handle404" });
Has anyone come across a cleaner way of doing this and handling 404 in web api?
EDIT 1
The above code DOES affect my MVC routes.
How can i add "api" to "{*url}"?... if tried many different ways and no dice.
Had the exact same issue. After some research and trial and error, I was able to find a working solution.
I went with a RoutePrefix solution and I tried to implement something similar to how the MVC controllers used HandleUnknownAction in a base controller.
With the help from this post: .NET WebAPI Attribute Routing and inheritance to allow for route inheritance, I created a base controller for my web APIs with a HandleUnknownAction method like this:
public abstract class WebApiControllerBase : ApiController {
[Route("{*actionName}")]
[AcceptVerbs("GET", "POST", "PUT", "DELETE")]//Include what ever methods you want to handle
[AllowAnonymous]//So I can use it on authenticated controllers
[ApiExplorerSettings(IgnoreApi = true)]//To hide this method from helpers
public virtual HttpResponseMessage HandleUnknownAction(string actionName) {
var status = HttpStatusCode.NotFound;
//This is custom code to create my response content
//....
var message = status.ToString().FormatCamelCase();
var content = DependencyService
.Get<IResponseEnvelopeFactory>()
.CreateWithOnlyMetadata(status, message);
//....
return Request.CreateResponse(status, content);
}
}
If you don't want to go down the inheritance path, you can always put the method directly into the controller you want to apply the functionality on.
This allows me to use route prefixes that handle custom not found messages that pertain to specific controllers as I have both back-office and public public facing APIs.
If a URL does not apply to an ApiController the default Error controller will handle the not found as usual.

ASP.NET Web API controlling success code (200 versus 201)

Is there a way to specify the success return code for a method in Web API controller?
My initial controller was structured like below
public HttpResponseMessage PostProduct(string id, Product product)
{
var product= service.CreateProduct(product);
return Request.CreateResponse(HttpStatusCode.Created, product);
}
However, there is drawback to the above approach when you generate Web API help pages. The Web API Help page API cannot automatically decode that the strongly typed Product is the response and hence generate a sample response object in its documentation.
So I go with the below approach, but here the success code is OK (200) and not Created (201). Anyway I can control the success code of the method using some attribute style syntax? Plus, I would also like to set the Location header to the URL where the created resource is available - again, this was easy to do when I was dealing with HttpResponseMesage.
public Product PostProduct(string id, Product product)
{
var product= service.CreateProduct(product);
return product;
}
Regarding your observation below:
However, there is drawback to the above approach when you generate Web API help pages. The Web API Help page API cannot automatically decode that the strongly typed Product is the response and hence generate a sample response object in its documentation.
You can take a look at HelpPageConfig.cs file that gets installed with HelpPage package. It has an example exactly for a scenario like yours where you can set the actual type of the response.
In latest version (5.0 - currently RC) of Web API we have introduced an attribute called ResponseType which you can use to decorate the action with the actual type. You would be able to use this attribute for your scenario.
I do this:
[HttpGet]
public MyObject MyMethod()
{
try
{
return mysService.GetMyObject()
}
catch (SomeException)
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content =
new StringContent("Something went wrong.")
});
}
}
If you don't get what you expected, throw a HttpResponseException.

Categories