首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将字符串发送到ASP.NET Web Api应用程序-返回null

将字符串发送到ASP.NET Web Api应用程序-返回null
EN

Stack Overflow用户
提问于 2012-12-08 05:11:51
回答 7查看 125.3K关注 0票数 45

我正在尝试将字符串从客户端传输到ASP.NET MVC4应用程序。

但我无法接收字符串,它可能是null或无法找到post方法(404错误)

用于传输字符串的客户端代码(控制台应用程序):

代码语言:javascript
运行
复制
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:49032/api/test");
request.Credentials = new NetworkCredential("user", "pw");
request.Method = "POST";
string postData = "Short test...";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;

Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

WebResponse response = request.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
dataStream = response.GetResponseStream();

StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
reader.Close();
dataStream.Close();
response.Close();
Console.ReadLine();

ASP.NET网络Api控制器:

代码语言:javascript
运行
复制
public class TestController : ApiController
{
    [Authorize]
    public String Post(byte[] value)
    {
        return value.Length.ToString();
    }
}

在这种情况下,我可以调用"Post“方法,但”NULL“是值。如果我将方法签名改为(字符串值),那么它将永远不会被调用。

即使“没有”Authorize设置,它也有同样奇怪的行为。->,所以它与用户身份验证无关。

你知道我做错了什么吗?我很感谢你的帮助。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-12-08 05:56:13

您似乎在Web API控制器操作中使用了一些[Authorize]属性,我不明白这与您的问题有什么关系。

那么,让我们开始练习吧。下面是一个简单的Web API控制器可能的样子:

代码语言:javascript
运行
复制
public class TestController : ApiController
{
    public string Post([FromBody] string value)
    {
        return value;
    }
}

和消费者的关系:

代码语言:javascript
运行
复制
class Program
{
    static void Main()
    {
        using (var client = new WebClient())
        {
            client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
            var data = "=Short test...";
            var result = client.UploadString("http://localhost:52996/api/test", "POST", data);
            Console.WriteLine(result);
        }
    }
}

您无疑会注意到Web API控制器属性的[FromBody]装饰,以及客户端POST数据的=前缀。我建议您阅读有关的文章以更好地理解这些概念。

[Authorize]属性而言,这可以用来防止服务器上的某些操作只能由经过身份验证的用户访问。实际上,很不清楚你想要实现什么,顺便说一句,here.You应该在你的问题中更清楚地说明这一点。您是否正在尝试了解参数绑定在ASP.NET Web API中的工作原理(如果这是您的目标,请阅读我链接的文章),或者正在尝试进行一些身份验证和/或授权?如果第二个是您的情况,您可能会发现我在此主题上编写的following post很有趣,可以帮助您入门。

如果在阅读完我链接的资料后,你会像我一样对自己说,天哪,我所需要做的就是将一个字符串发送到服务器端端点,然后我需要做所有这些事情?不行。然后查看ServiceStack。您将有一个与Web API进行比较的良好基础。我不知道微软的人在设计Web API时是怎么想的,但说真的,我们应该为我们的HTML (想想Razor)和REST东西有单独的基本控制器?这不可能是严重的。

票数 60
EN

Stack Overflow用户

发布于 2012-12-08 09:29:36

如果您接受使用HTTP的事实,则Web API工作得非常好。当您开始尝试假装通过网络发送对象时,它开始变得混乱。

代码语言:javascript
运行
复制
 public class TextController : ApiController
    {
        public HttpResponseMessage Post(HttpRequestMessage request) {

            var someText = request.Content.ReadAsStringAsync().Result;
            return new HttpResponseMessage() {Content = new StringContent(someText)};

        }

    }

这个控制器将处理一个HTTP请求,从有效负载中读取一个字符串,并将该字符串返回。

您可以通过传递StringContent的实例来使用HttpClient调用它。StringContent将是默认的,使用文本/纯文本作为媒体类型。这正是你想要通过的。

代码语言:javascript
运行
复制
    [Fact]
    public void PostAString()
    {

        var client = new HttpClient();

        var content = new StringContent("Some text");
        var response = client.PostAsync("http://oak:9999/api/text", content).Result;

        Assert.Equal("Some text",response.Content.ReadAsStringAsync().Result);

    }
票数 36
EN

Stack Overflow用户

发布于 2012-12-08 05:26:27

我使用这段代码来发布HttpRequests。

代码语言:javascript
运行
复制
/// <summary>
        /// Post this message.
        /// </summary>
        /// <param name="url">URL of the document.</param>
        /// <param name="bytes">The bytes.</param>
        public T Post<T>(string url, byte[] bytes)
    {
        T item;
        var request = WritePost(url, bytes);

        using (var response = request.GetResponse() as HttpWebResponse)
        {
            item = DeserializeResponse<T>(response);
            response.Close();
        }

        return item;
    }

    /// <summary>
    /// Writes the post.
    /// </summary>
    /// <param name="url">The URL.</param>
    /// <param name="bytes">The bytes.</param>
    /// <returns></returns>
    private static HttpWebRequest WritePost(string url, byte[] bytes)
    {
        ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;

        HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
        Stream stream = null;
        try
        {
            request.Headers.Clear();
            request.PreAuthenticate = true;
            request.Connection = null;
            request.Expect = null;
            request.KeepAlive = false;
            request.ContentLength = bytes.Length;
            request.Timeout = -1;
            request.Method = "POST";
            stream = request.GetRequestStream();
            stream.Write(bytes, 0, bytes.Length);
        }
        catch (Exception e)
        {
            GetErrorResponse(url, e);
        }
        finally
        {
            if (stream != null)
            {
                stream.Flush();
                stream.Close();
            }
        }
        return request;
    }

关于您的代码,在不使用content.Type (request.ContentType = "application/x-www-form-urlencoded";)的情况下尝试一下

更新

我认为问题出在您试图检索值的方式。当您通过Stream执行POST和发送字节时,它们不会作为参数传递到操作中。您需要通过服务器上的流检索字节。

在服务器上,尝试从stream获取字节。下面的代码是我使用的代码。

代码语言:javascript
运行
复制
     /// <summary> Gets the body. </summary>
     /// <returns> The body. </returns>
     protected byte[] GetBytes()
     {
       byte[] bytes;
        using (var binaryReader = new BinaryReader(Request.InputStream))
        {
            bytes = binaryReader.ReadBytes(Request.ContentLength);
        }

         return bytes;
     }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13771032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档