从 API 重定向

Gre*_*ens 1 rest asp.net-mvc asp.net-web-api

我正在尝试学习/扩展我对 .NET MVC/REST/API 和 Web-sockets/SignalR 的知识。为此,我正在实施一个聊天应用程序。

我有一个典型的 MVC 介绍页面,它在表单中获取用户名和电子邮件地址,并将该数据提交到 RESTFul API,然后将新用户添加到数据库中。

<form class="form-horizontal" role="form" action="/api/GroopsAPIUsers" method="POST">
Run Code Online (Sandbox Code Playgroud)

在该页面(?)的控制器内部,我将用户重定向到一个页面,在那里他们可以选择他们想要进入的房间。

public HttpResponseMessage  Post( GroopsUser userValue)
{
     userValue.ID =  Guid.NewGuid();
     bool results = groopsRepository.AddNewUser(userValue);
     //   return results;

     var response = Request.CreateResponse(HttpStatusCode.Redirect);

      //from http://stackoverflow.com/questions/11324711/redirect-from-asp-net-web-api-post-action

     string fullyQualifiedUrl = Request.RequestUri.GetLeftPart(UriPartial.Authority);
     response.Headers.Location = new Uri (fullyQualifiedUrl + "/home/rooms/?userID=" + userValue.ID);

     return response;

}
Run Code Online (Sandbox Code Playgroud)

但这感觉不对。似乎 API 应该只执行 CRUD 操作,而与用户重定向到的页面无关。

这是错误的方法吗?如果是这样,有人可以指出我正确的方向吗?(我不确定我是否正确使用了所有这些术语)

...格雷戈里

Tob*_*ias 8

I can see why you don't think it feels right. Usually, you would design your Web API in such a way, that it is platform agnostic, so the only thing it cares about is the incoming HTTP requests, and operations based on those. When you redirect a request to another URL, you are designing around the web browser, thus constraining yourself to that one platform. Sometimes that's what you need, sometimes it isn't. (if it indeed is what you need, then you should probably stick to just regular Asp.NET MVC, and not Web Api)

Instead of what you have now, you could make your application more flexible by returning, for example, a 200 status code from your controller, after a successful operation. That way, it is up to the client-side application to decide what to do from there. (This is where you redirect, if your client-side application is browser-based.)

So how exactly do you achieve this with your browser application? You might already have guessed it, but the answer is Javascript. Instead of making a synchronous POST request to your API, via your form, you could make the request async, and then wait for the response from the server. Then you can take an appropriate action, based on what the response contains.

A quick example:

Controller

public HttpResponseMessage  Post(GroopsUser userValue)
{
     userValue.ID =  Guid.NewGuid();
     bool results = groopsRepository.AddNewUser(userValue);

     var response = Request.CreateResponse<GroopsUser>(HttpStatusCode.OK, userValue);

     return response;
}
Run Code Online (Sandbox Code Playgroud)

Form

<form class="form-horizontal" id="group-form" onsubmit="return addToGroup()" role="form" action="/api/GroopsAPIUsers" method="POST">
Run Code Online (Sandbox Code Playgroud)

Javascript (jQuery)

<script>
    function addToGroup()
    {
        $.ajax({
                type: "POST",
                url: $('#group-form').attr('action'),
                data: $('#group-form').serialize(),
                dataType: "json",
                success: function(data) {
                    window.location.replace('/home/rooms/?userID=' + data.ID);
                },
                error: function(){
                      alert('error handing here');
                }
            });
        return false;
    }

</script>
Run Code Online (Sandbox Code Playgroud)

If anything is unclear, or if I'm mistaken about anything, please let me know!