How to deserialize json to .net type and return it as string

I'm trying to send a POST request using Fiddler as so:

POST http://localhost:50196/api/values/json HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json;
Host: localhost:50196
Content-Length: 73

{"ssn":1605789787,"creditScore":598,"loanAmount":10.0,"loanDuration":360}

This is my WebAPI controller, where I deserialize it to a .NET type which is my POCO. Then I get the ssn and generate a rate which I then want to return.

public class ValuesController : ApiController
{
    [ActionName("json")]
    public string Post(string request)
    {
        var json = JsonConvert.DeserializeObject<JsonModel>(request);
        var ss = json.Ssn;

        var random = new Random();
        var interestRate = random.Next(100, 500);
        var rate = interestRate / 100;

        var delta = "{"ssn":" + ss + ","interestRate":" + rate + "}";

        return delta;

    }

}

POCO:

public class JsonModel
{
    [JsonProperty("ssn")]
    public string Ssn { get; set; }
    [JsonProperty("creditScore")]
    public int CreditScore { get; set; }
    [JsonProperty("loanAmount")]
    public decimal LoanAmount { get; set; }
    [JsonProperty("loanDuration")]
    public int LoanDuration { get; set; }
}

WebAPI config:

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new {action = @"[a-zA-Z]+", id = @"*"}
        );
    }

This is the error I'm getting:

[HttpException]: The controller for path '/api/values/json' was not found or does not implement IController. ved System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) ved System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) ved System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) ved System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) ved System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) ved
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) ved
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() ved System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)


Firstly, you are completely missing out in ASP.NET MVC model binding capabilities here, instead of accepting a JSON string in the action and then deserializing, just expect the model and let the framework do the binding for you eg

public HttpResponseMessage Post(JsonModel model)
{
    ...
}

Secondly, your exception is due to a routing problem. You are trying to post to api/values/json which is the equivalent to api/{controller}/{action} . However, as you can see you don't have an action which maps to that particular route because your only route expects an id parameter (but your action contains a request parameter).

Switching to using the model directly in the view should be enough to fix this issue and should work posting directly to api/values/json .


I thought that { id = RouteParameter.Optional } was optional as in it would accept the ID

That generally would be the case, however, in your route you have a constraint set on the id which says it has to contain some value - this renders your default value obsolete.


I think your controller can accept your POCO type directly, no need to serialize from the string by hand:

public HttpResponseMessage Post(HttpRequestMessage request, [FromBody]JsonModel)

I'm not sure that's the problem, though. When using WebAPI, I'd stay away from the ActionName attribute. I think it's a lot cleaner to have a separate controller for each type with simple Get/Post, etc. methods. So, in your case:

Controller:

public HttpResponseMessage Post(HttpRequestMessage request, [FromBody]JsonModel)
{}

Then you simply post to:

api/values

...and, finally, your route config:

routeTemplate: "api/{controller}/{id}"
链接地址: http://www.djcxy.com/p/36810.html

上一篇: 事件查看器在服务器上显示警告

下一篇: 如何将json反序列化为.net类型并将其作为字符串返回