繁体   English   中英

在Web Api中接收发布请求时处理无效的正文

[英]Handle invalid Body when receiving Post Request in Web Api

我有一个第三方,它将向我正在制作的Web Api服务发送Post请求。

我有一个像

public returnObject PostFromThirdPartyObject(ThirdPartyObject JSONobj)
{
    // Process Object
    return returnObject;
}

当我发送正确的对象时,这工作正常。

问题是当发送无效对象时, ThirdPartyObject将填充为空。

我希望能够捕获无效对象,以便可以记录和诊断问题,因为我不信任第三方规范。

如何处理与预期类型不匹配的Post正文?


编辑:用于测试是否需要更改的代码

string body = JsonConvert.SerializeObject(ThirdPartyObject);
var cfReq = (HttpWebRequest)WebRequest.Create(url);
cfReq.ContentType = "application/json";
cfReq.Method = "Post";
cfReq.ContentLength = body.Length;
var byteArray = Encoding.UTF8.GetBytes(body);
var stream = cfReq.GetRequestStream();
stream.Write(byteArray, 0, body.Length);

var httpResponse = (HttpWebResponse)cfReq.GetResponse();
var stringResponse = string.Empty;
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    stringResponse = streamReader.ReadToEnd();
}

编辑2:使用对象真的很糟糕的解决方法,希望有人可以发布更正确的方法

public Status PostFromThirdPartyObject([FromBody] object sObject)
{
    ThirdPartyObject obj = null;
    string sRequest = null;
    try
    {
        sRequest = JsonConvert.SerializeObject(sObject);
        LogRequest(sRequest);
        var setting = new JsonSerializerSettings();
        setting.MissingMemberHandling = MissingMemberHandling.Error;
        obj = JsonConvert.DeserializeObject<ThirdPartyObject>(sRequest, setting);
    }
    catch
    {
        if (sObject != null)
        {
            return Error
        }
        else
        {
            return NullError
        }
    }
    return processThirdPartyObject(obj);
}

要扩展Shaukat Sarwar的答案,您可以从HttpContext访问正文。

public returnObject PostFromThirdPartyObject(ThirdPartyObject JSONobj)
{
    var content = new System.IO.StreamReader(HttpContext.Current.Request.InputStream /*, Encoding here if necessary */)
                    .ReadToEnd();

    // Process Object
    return returnObject;
}

记住要在StreamReader使用适当的编码(最有可能是UTF8)。

您可能还想看看ModelState.IsValid ,如另一个答案所述。 只需将模型中的所有必需属性标记为[Required] (否则ModelState.IsValid始终为true),并在那里获取无效请求的原始内容以将其保存。

public returnObject PostFromThirdPartyObject(ThirdPartyObject JSONobj)
{
    if (!ModelState.IsValid)
    {
        var content = new StreamReader(HttpContext.Current.Request.InputStream /*, Encoding here if necessary */)
                .ReadToEnd();

        // Do something with the raw content here

        return BadRequest(ModelState);
    }

    // Process Object
    return returnObject;
}

另请参阅: ASP.NET Web API中的模型验证

会有一些不错的选择,但是现在,您可以做的是将流作为输入并以字符串形式读取。 您的客户确切地在该字符串中发布了内容。 您可以像使用JsonConvert.DeserializeObject<ThirdPartyObject>(inpString)一样,使用Newtonsoft.Json.JsonConvert将字符串反序列化为ThirdPartyObject。

你的功能可能是这样的:

public returnObject PostFromThirdPartyObject(Stream jsonStream)
{
        string sRequest = String.Empty;
        StreamReader stmRequest = new StreamReader(input, System.Text.Encoding.UTF8);
        sRequest = stmRequest.ReadToEnd();
        ThirdPartyObject obj = null;

        try{
            obj = JsonConvert.DeserializeObject<ThirdPartyObject>(sRequest)
           }
        catch
        {
           //you have the object posted by your client in sRequest
           //do whatever you want
        }

    // obj is your object to process
    // Process Object
    return returnObject;
}

您的客户不需要在其末端进行任何更改。

尝试使用ModelState.IsValid():

public returnObject PostFromThirdPartyObject([FromBody] ThirdPartyObject JSONobj)
{
    if(!ModelState.IsValid()) {
        // Do someting
    }
    // Process Object
    return returnObject;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM