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

时间:2013-12-06 14:37:34

标签: c# json asp.net-web-api

我正在尝试使用Fiddler发送POST请求:

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}

这是我的WebAPI控制器,我将其反序列化为.NET类型,这是我的POCO。然后我得到ssn并生成一个我想要返回的速率。

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配置:

    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 = @"\*"}
        );
    }

这是我得到的错误:

  

[HttpException]:路径'/ api / values / json'的控制器   未找到或未实现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&amp;控制器,IControllerFactory&amp;厂)   ved System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase)   httpContext,AsyncCallback回调,对象状态)ved   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext,   AsyncCallback回调,对象状态)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,   布尔和放大器; completedSynchronously)

2 个答案:

答案 0 :(得分:1)

我认为你的控制器可以直接接受你的POCO类型,不需要手工序列化字符串:

public HttpResponseMessage Post(HttpRequestMessage request, [FromBody]JsonModel)
但是,我不确定这是不是问题。使用WebAPI时,我会远离ActionName属性。我认为使用简单的Get / Post等方法为每种类型设置单独的控制器会更加清晰。所以,在你的情况下:

控制器:

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

然后你只需发帖到:

api/values

...最后,你的路线配置:

routeTemplate: "api/{controller}/{id}"

答案 1 :(得分:1)

首先,你完全错过了ASP.NET MVC模型绑定功能,而不是在动作中接受JSON字符串然后反序列化,只是期望模型并让框架为你做绑定,例如

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

其次,您的例外是由于路由问题。您正试图发布到api/values/json,这相当于api/{controller}/{action}。但是,您可以看到没有映射到该特定路由的操作,因为您的唯一路径需要id参数(但您的操作包含request参数)。

直接在视图中切换到使用模型应足以解决此问题,并应直接发布到api/values/json


  

我认为{ id = RouteParameter.Optional }是可选的,因为它会接受ID

通常会出现这种情况,但是,在您的路线中,您在id上设置了一个约束,表示它必须包含某些值 - 这会使您的默认值过时。