1

I have a Entity Framework API Controller that was generated, I am now trying to add a new method to it:

[ResponseType(typeof(LCPreview))]
public IHttpActionResult ValidateEmail(string email)
{
    LCPreview lCPreview = db.Data.Find(5);
    if (lCPreview == null)
    {
        return NotFound();
    }

    return Ok(lCPreview);
}

but when I run this, I get this error:

The request is invalid. The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Http.IHttpActionResult GetLCPreview(Int32)' in 'Astoria.Controllers.PreviewLCAPIController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}
6
  • did you check the object returned from db.Data.Find call? It might be having a null value for id field. Commented Nov 10, 2016 at 19:27
  • I put in a a break point, its not hitting that new method at all Commented Nov 10, 2016 at 19:35
  • 1
    route conflict. it is hitting another route that matched the request. Show how you configure your routes setup. and the url being requested Commented Nov 10, 2016 at 19:37
  • 1
    From the stack trace, it looks like it is hitting GetLCPreview(Int32) with a null parameter. Commented Nov 10, 2016 at 19:50
  • 1
    I'm going to go out on a limb and and assume you are using a GET request to try and hit this method. By default, I believe that any route that doesn't have get in the name (or is marked with an HTTPGet attibute) will default to POST. So you will either need to mark this as a GET request or change your call to a POST Commented Nov 10, 2016 at 20:28

1 Answer 1

1

via convention-based routing the route table is unable to differentiate between the two actions and is selecting the GetLCPreview action based on Get prefix convention.

Given that your route configuration is already enabling attribute routing this means that paramater constraints can be used to help differentiate the routes.

[RoutePrefix("api/PreviewLCAPI")]
public class PreviewLCAPIController : ApiController {

    //GET api/PreviewLCAPI/5 <- only when the value is an int will it match.
    [Route("{id:int}")]
    [HttpGet]
    public IHttpActionResult GetLCPreview(int id) { ... }

    //GET api/PreviewLCAPI/[email protected]/
    [Route("{email}"]
    [HttpGet]
    [ResponseType(typeof(LCPreview))]
    public IHttpActionResult ValidateEmail(string email) { ... }
}

Note that the dot (.) in the email will cause you some issues if entered without the slash (/) at the end. The framework will think it's looking for a file and error out.

If the intention was to send the email address then use POST and include email in the body.

//POST api/PreviewLCAPI
[Route("")]
[HttpPost]
[ResponseType(typeof(LCPreview))]
public IHttpActionResult ValidateEmail([FromBody] string email) { ... }

sending it in the request body avoid any issues with the email format in the url.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.