简体   繁体   English

如何在Web API帮助页面文档中显示仅响应的参数?

[英]How to display parameter in Web API help page documentation for Response only?

I've configured Web API help page documentation. 我已经配置了Web API帮助页面文档。

I am having below class which would be inherited in other model classes. 我正在下面的类,它将在其他模型类中继承。

public class ResponseBase
{
    public string ErrorReason { get; set; }
    [IgnoreDataMember]
    public bool IsRejected { get; set; }
}

I don't want IsRejected to be serialized and available in response so I decorated it with IgnoreDataMember attribute. 我不希望IsRejected被序列化并在响应中可用,因此我使用IgnoreDataMember属性对其进行了修饰。

Example of model class that inherits ResponseBase. 继承ResponseBase的模型类示例。

public class Reading : ResponseBase
{
    //Other properties
}

I've below method in my Web API Controller: 我的Web API控制器中有以下方法:

[HttpPost]
[ValidationResponseFilter]
[Route("")]
[ResponseType(typeof(Reading))]
public IHttpActionResult Add(List<Reading> readingList)
{
    //Logic here
}

Now for the documentation of request parameter which is list of Reading objects, it will list down all the properties of Reading along with ResponseBase class(inheritance). 现在,对于作为Reading对象列表的请求参数的文档,它将列出Reading的所有属性以及ResponseBase类(继承)。 I want help page documentation to list down ErrorReason as one of the parameter in Response only. 我希望帮助页面文档将ErrorReason列为仅响应中的参数之一。

Is there any configuration I can do other than setting attribute [ApiExplorerSettings(IgnoreApi = true)] on ErrorReason? 除了在ErrorReason上设置属性[ApiExplorerSettings(IgnoreApi = true)] ,我还能做任何配置吗? If I do that, ErrorReason will not be available in both Request and Response Parameters. 如果我这样做,ErrorReason将不会在请求和响应参数中可用。 I want to display it in Response Parameters list only. 我想只在响应参数列表中显示它。

Generally, the best practice is to create a custom object that matches exactly what you want to accept. 通常,最佳做法是创建一个与您要接受的内容完全匹配的自定义对象。 One of the reasons for this is security. 其中一个原因是安全性。 See 'over-posting' and 'under-posting' : http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api To do this you would create a new object with only the properties you need. 请参阅“过度发布”和“发布不足”: http//www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api待办事项这样你就可以创建一个只有你需要的属性的新对象。

public class ResponseBaseVM
    {
        public string ErrorReason { get; set; }
        /*public bool IsRejected { get; set; }*/ 
    }
public class ReadingVM : ResponseBaseVM
    {
        //Other properties that you only want available to user
    }

Then you would take in List of ReadingVM but the response type would still be typeof(reading) 然后你会接受ReadingVM列表,但响应类型仍然是typeof(阅读)

[HttpPost]
[ValidationResponseFilter]
[Route("")]
[ResponseType(typeof(List<Reading>))] //will still display response with IsRejected
public IHttpActionResult Add(List<ReadingVM> readingListVM)
{
    //Logic here
}

--- Work Around --- ---工作---

Again, I think you should follow the method above. 我再次认为你应该遵循上面的方法。 You asked for a work around and here it is. 你要求解决这个问题。 Find your 'GenerateApiModel' method in the HelpPageConfigurationExtensions.cs class and repalce it with this: 在HelpPageConfigurationExtensions.cs类中找到'GenerateApiModel'方法并使用以下方法重新生成它:

private static HelpPageApiModel GenerateApiModel(ApiDescription apiDescription, HttpConfiguration config)
{
    HelpPageApiModel apiModel = new HelpPageApiModel()
    {
        ApiDescription = apiDescription,
    };

    ModelDescriptionGenerator modelGenerator = config.GetModelDescriptionGenerator();
    HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator();
    GenerateUriParameters(apiModel, modelGenerator);
    GenerateRequestModelDescription(apiModel, modelGenerator, sampleGenerator);
    GenerateResourceDescription(apiModel, modelGenerator);
    GenerateSamples(apiModel, sampleGenerator);

    //This will remove request body parameters from your Api Help Page matching 'IsRejected'
    var isRejectedParameter = apiModel.RequestBodyParameters.SingleOrDefault(x => x.Name == "IsRejected");
    if (isRejectedParameter != null)
        apiModel.RequestBodyParameters.Remove(isRejectedParameter);

    //This will remove elements with 'IsRejected' for the Help Page sample requests 
    var sampleRequests = new Dictionary<MediaTypeHeaderValue, object>();
    foreach (var kvp in apiModel.SampleRequests)
    {
        //1.) iterate through each object in SampleRequests dictionary.
        //2.) modify the json or xml to remove the "IsRejected" elements
        //3.) assign modified results to a new dictionary
        //4.) change the HelpPageApiModel. SampleRequests setter to be not private
        //5.) assign new dictionary to HelpPageApiModel.SampleRequests
        if (Equals(kvp.Key, new MediaTypeHeaderValue("application/json")))
        {
            var jObject = JObject.Parse(kvp.Value.ToString());
            jObject.Remove("IsRejected");
            sampleRequests.Add(new MediaTypeHeaderValue("application/Json"), jObject.ToString());
        }
        else if(Equals(kvp.Key, new MediaTypeHeaderValue("text/json")))
        {
            //do stuff
        }
        else if (Equals(kvp.Key, new MediaTypeHeaderValue("application/xml")))
        {
            //do stuff
        }
        else if (Equals(kvp.Key, new MediaTypeHeaderValue("text/xml")))
        {
            //do stuff
        }
        else
        {
            //form urlencoded or others
            sampleRequests.Add(kvp.Key,kvp.Value);
        }
    }
    apiModel.SampleRequests = sampleRequests;

    return apiModel;
}

Now as you can see 'IsRejected' exists in the Response, but not the Reqest. 现在你可以看到响应中存在'IsRejected',但不是Reqest。 请求帮助页面覆盖

I suggest you use HTTP Status Codes as a way of conveying success or failure, such as they are meant to, unless there's a specific reason you want to return the errors as a HTTP Status Code 200 (OK) instead. 我建议您使用HTTP状态代码作为传达成功或失败的方式,例如它们的意图,除非有特定原因要将错误作为HTTP状态代码200(OK)返回。

The general way of dealing with such a scenario is to return 2xx-status codes when everything is ok, and 4xx or 5xx status codes when an error occurred. 处理这种情况的一般方法是在一切正常时返回2xx状态代码,在发生错误时返回4xx或5xx状态代码。 This way the client can clearly distinguish error situations from successful operations. 通过这种方式,客户可以清楚地区分错误情况和成功操作。

A good blog post on the subject on error handling can be found on Exception Not Found -blog, from where this good example of a controller action is taken: 有关错误处理主题的好博客文章可以在Exception Not Found -blog上找到 ,从这里可以获得控制器操作的这个好例子:

[Route("CheckId/{id}")]
[HttpGet]
public IHttpActionResult CheckId(int id)  
{
    if (id > 100)
    {
        var message = new HttpResponseMessage(HttpStatusCode.BadRequest)
        {
            Content = new StringContent("We cannot use IDs greater than 100.")
        };
        throw new HttpResponseException(message);
    }
    return Ok(id);
}

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

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