简体   繁体   English

Asp.net 5 web api 自定义操作结果

[英]Asp.net 5 web api Custom ActionResult

Here is my implementation of Custom ActionResult这是我对 Custom ActionResult 的实现

public class ResultData<T>
{
    public string Code { get; set; }
    public string Massage { get; set; }
    public T Result { get; set; }
}

public class BaseApiResult<T> : JsonResult
{
    public BaseApiResult() : base(null)
    {
        ContentType = "application/json";
    }

    public IActionResult Success(T result)
    {
        Value = new ResultData<T>
        {
            Code = "2000",
            Massage = "Sucsess",
            Result = result
        };

        StatusCode = 200;
     
        return this;
    }

    public IActionResult Fail(T result, string code, string massage)
    {
        Value = new ResultData<T>
        {
            Code = code,
            Massage = massage,
            Result = result
        };

        StatusCode = 400;

        return this;
    }

    public IActionResult ServerError(T result)
    {
        Value = new ResultData<T>
        {
            Code = "5000",
            Massage = "Internal Server Error",
            Result = result
        };

        StatusCode = 500;
       
        return this;
    }
}

Now this how we call it现在这就是我们所说的

    [HttpGet("GetProducts")]
    public IActionResult GetProducts()
    {
        try
        {
            var res = _entityFrameworkCoreService.GetAllProducts();

            if (res.Count <= 0)
            {
                return new BaseApiResult<string>().Fail(null, "4002", "NoRecord found");
            }

            return new BaseApiResult<IList<DtoProSubCat>>().Sucsees(res); ;
        }
        catch (Exception ex)
        {
            return new BaseApiResult<string>().ServerError(ex.Message);
        }
    }

Now what I what to ask about is: -现在我要问的是:-

1- is this a wrong implementation of ActionResult? 1- 这是 ActionResult 的错误实现吗?

2- is this implementation have performance issues? 2-这个实现有性能问题吗?

3- is there any enhancement to add to this implementation? 3-是否有任何增强功能可以添加到此实现中?

3- what is the best practice for Implementing Custom ActionResult? 3- 实现自定义 ActionResult 的最佳实践是什么?

The method above will still work fine, but personally I think it's not good.上面的方法还是可以的,但是个人觉得不太好。 First of all, what you really need is to return the results wrapped in ResultData.首先,您真正需要的是返回封装在 ResultData 中的结果。 This is considered a data model, rather than a behavior.这被认为是数据 model,而不是行为。 It should be known that IActionResult is not just the return data, but in the Asp MVC operation model, it is also the output handler for the HTTP server.要知道IActionResult不仅仅是返回数据,在Asp MVC操作model中,它也是HTTP服务器的output处理程序。

I propose some of the following solutions, which I believe will be more suitable.我提出以下几种方案,相信会比较合适。

Method 1: Create a base class for ControllerBase.方法一:为ControllerBase创建一个base class。 Eg:例如:

public class ControllerBase : Microsoft.AspNetCore.Mvc.Controller
{
    protected IActionResult MyResult <T> (int statusCode, ResultData<T> result)
    {
        var jsonResult = Json(result);
        jsonResult.StatusCode = statusCode;
        return jsonResult;
    }

    protected IActionResult Success <T> (T result)
    {
        return MyResult(200, new ResultData<T>
        {
            Code = "2000",
            Massage = "Sucsess",
            Result = result
        });
    }

    protected IActionResult Fail <T> (T result, string code, string massage)
    {
        return MyResult(400, new ResultData<T>
        {
            Code = code,
            Massage = massage,
            Result = result
        });
    }

    protected IActionResult ServerError<T>(T result)
    {
        return MyResult(500, new ResultData<T>
        {
            Code = "5000",
            Massage = "Internal Server Error",
            Result = result
        });
    }
}

/** implement */
public class HomeController : ControllerBase
{
    [HttpGet("GetProducts")]
    public IActionResult GetProducts()
    {
        try
        {
            IList<DtoProSubCat> res = new List<DtoProSubCat>() { new DtoProSubCat() }; //

            if (res.Count <= 0)
            {
                return Fail<string>(null, "4002", "NoRecord found");
            }

            return Success<IList<DtoProSubCat>>(res); ;
        }
        catch (Exception ex)
        {
            return ServerError(ex.Message);
        }
    }
}

A somewhat similar way is to create an extensions functions for Controller or you will create a static class that contains functions that process data.有点类似的方法是为 Controller 创建一个扩展函数,或者您将创建一个 static class 包含处理数据的函数。

Method 2: Create a specific class for each response behavior.方法二:为每个响应行为创建一个具体的class。 Eg:例如:

public class SuccessResult <T> : JsonResult
{
    public SuccessResult (T result)
        : base(new ResultData<T>
        {
            Code = "2000",
            Massage = "Sucsess",
            Result = result
        })
    {
        StatusCode = 200;
    }
}

public class FailResult<T> : JsonResult
{
    public FailResult(T result, string code, string massage)
        : base(new ResultData<T>
        {
            Code = code,
            Massage = massage,
            Result = result
        })
    {
        StatusCode = 400;
    }
}

public class ServerErrorResult<T> : JsonResult
{
    public ServerErrorResult(T result)
        : base(new ResultData<T>
        {
            Code = "5000",
            Massage = "Internal Server Error",
            Result = result
        })
    {
        StatusCode = 500;
    }
}

/** implement */
public class HomeController : Controller
{
    [HttpGet("GetProducts")]
    public IActionResult GetProducts()
    {
        try
        {
            IList<DtoProSubCat> res = new List<DtoProSubCat>() { new DtoProSubCat() }; //

            if (res.Count <= 0)
            {
                return new FailResult<string>(null, "4002", "NoRecord found");
            }

            return new SuccessResult<IList<DtoProSubCat>>(res); ;
        }
        catch (Exception ex)
        {
            return new ServerErrorResult<string>(ex.Message);
        }
    }
}

The way you implement the above makes a few lines of command pointless, of course during the running of the application there is not much problem, but in the long run will affect the expansion or maintenance process.上面的实现方式使得几行命令毫无意义,当然在应用程序运行期间没有太大问题,但从长远来看会影响扩展或维护过程。 The above two ways help you protect the operating model of the function, minimize the source code, and minimize the meaningless command lines.以上两种方式帮你保护function的运行model,最小化源代码,最小化无意义的命令行。

what about this V2 as @Henry Trần gives a hint about it这个 V2 怎么样, @Henry Trần给出了一个提示

public class BaseApiResultV2
{
    private IActionResult SetResult<T>(int statusCode, ResultData<T> result)
    {
        JsonResult jsonResult = new(result)
        {
            StatusCode = statusCode,
            ContentType = "application/json"
        };

        return jsonResult;
    }

    public IActionResult Success<T>(T result)
    {
        return SetResult(StatusCodes.Status200OK,
            new ResultData<T>
            {
                Code = "2000",
                Massage = "Sucsess",
                Result = result
            });
    }

    public IActionResult Fail<T>(T result, string code, string massage)
    {
        return SetResult(StatusCodes.Status400BadRequest,
            new ResultData<T>
            {
                Code = code,
                Massage = massage,
                Result = result
            });
    }

    public IActionResult ServerError<T>(T result)
    {
        return SetResult(StatusCodes.Status500InternalServerError,
            new ResultData<T>
            {
                Code = "5000",
                Massage = "Internal Server Error",
                Result = result
            });
    }

    private struct ResultData<T>
    {
        public string Code { get; set; }
        public string Massage { get; set; }
        public T Result { get; set; }
    }
}

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

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