如何在MVC调用Web API中向用户显示错误消息?

时间:2017-05-31 12:49:35

标签: asp.net-mvc asp.net-web-api2

我正在研究一个调用Web API的MVC Web App。在我的Create(POST)方法中,用户将输入数据库中某些用户的电子邮件地址。只有在数据库中尚不存在电子邮件时,我才会检查是否输入电子邮件。如果它已经存在,我希望能够向用户显示错误消息“电子邮件已存在”。

我认为HttpStatusCode.NotFound, "Email exists already."会起作用,但我认为它只会在PostMan中显示。如何在MVC端显示类似ViewBag.ErrorMessage

API

public IHttpActionResult PostApprovedUsers(ApprovedUsers approvedUsers)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

if (!db.ApprovedUsers.Any(u => u.Email == approvedUsers.Email))
{
    db.ApprovedUsers.Add(approvedUsers);
    db.SaveChanges();
}
else
{
    return Content(HttpStatusCode.NotFound, "Email exists already.");
}
return CreatedAtRoute("DefaultApi", new { id = approvedUsers.Email }, approvedUsers);

MVC创建

public ActionResult Create([Bind(Include = "Email,FirstName,LastName")] ApprovedUsers approvedUsers)
{
    using (WebClient client = new WebClient())
    {
        token = Session.GetDataFromSession<string>("access_token");
            client.Headers.Add("authorization", "Bearer " + token);
            client.UploadValues(apiUrl, "POST", new NameValueCollection()
            {                      
                { "Email", approvedUsers.Email },
                { "FirstName",approvedUsers.FirstName },
                { "LastName",approvedUsers.LastName }
            });                
    }
    return RedirectToAction("Index");
}

2 个答案:

答案 0 :(得分:1)

您所看到的主要问题是您实际上并没有使用webclient的返回值做任何事情。这是可以的,因为基于我们的讨论,所有内容都在同一个项目中,并且不会是您希望如何使用ASP.NET MVC和Web API执行此操作。

由于这些都在同一个项目中,我们确实希望结合常用功能,但不能在控制器中。应该将DB服务抽象为单独的项目(或类),然后使用某种形式的IoC Container将其注入到两个控制器中。有几个选项可用,我个人通常使用Ninject作为我的.NET项目。

假设您具有该功能,则MVC控制器和API控制器应该针对该抽象进行编程。 Interface based programming是.NET最佳工作方式。

考虑到这一点,您的新API控制器将如下所示:

public IHttpActionResult PostApprovedUsers([Bind(Include="Email, FirstName, LastName")]ApprovedUser approvedUser)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        if (_db.UserExists(approvedUser))
        {
            return Content(HttpStatusCode.NotFound, "Email exists Already");
        }

        _db.AddUser(approvedUser);
        return CreatedAtRoute("DefaultApi", new {id = approvedUser.Email}, approvedUser);
    }

其中_db是注入控制器的服务。请注意,如何检查用户是否存在以及添加用户等常见功能都包含在抽象之后:

public interface IMyFakeDbService
{
    IQueryable<ApprovedUser> ApprovedUsers { get; }

    int RemoveUser(ApprovedUser user);

    int RemoveUser(string email);

    bool UserExists(ApprovedUser user);

    void AddUser(ApprovedUser user);
}

然后将我们带到您的MVC控制器。同样的原则适用;因为所有常见功能都在db服务中,只需将其注入控制器而不是调用API控制器。您将看到可以在此处使用ModelState.AddModelError将信息传回视图。

public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Create([Bind(Include = "Email, FirstName, LastName")]ApprovedUser user)
    {
        if (ModelState.IsValid)
        {
            if (!_db.UserExists(user))
            {
                _db.AddUser(user);
                return RedirectToAction("Index");
            }
            ModelState.AddModelError("","A user with that email already exists");
        }
        return View();
    }

<强>最后

  1. 我使用完整的项目here
  2. 创建了一个公共git仓库
  3. 数据库调用应为async。如果不是,那你就是在浪费服务器资源
  4. 如果你想快速学习MVC我建议Pro ASP.NET MVC 5Pro ASP.NET Web API2

答案 1 :(得分:0)

我总是使用Ok<T>,其中T是我定义的模型,它有3个变量,一个将标识状态(true,false),一个将是一个字符串消息,一个将具有数据类型{ {1}}我需要在终点接收,然后您可以根据需要修改错误消息 在你的情况下而不是这个

List<object>

我会用这样的东西替换它

return BadRequest(ModelState);

然后,一旦你获得了你的内容,你可以将它想象成你的对象

return Ok<MyResponse>(new MyResponse{ Message = "Error Message Here", Status = false});