Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Asp.Net内核中使用POST方法重定向到URL_C#_Url_Redirect_Url Rewriting_Asp.net Core - Fatal编程技术网

C# 在Asp.Net内核中使用POST方法重定向到URL

C# 在Asp.Net内核中使用POST方法重定向到URL,c#,url,redirect,url-rewriting,asp.net-core,C#,Url,Redirect,Url Rewriting,Asp.net Core,我有一个简单的url重写器: private static void RedirectToAPI(RewriteContext context) { var request = context.HttpContext.Request; if (request.Path.Value.StartsWith("/apiendpoint", StringComparison.OrdinalIgnoreCase)) {

我有一个简单的url重写器:

    private static void RedirectToAPI(RewriteContext context)
    {
        var request = context.HttpContext.Request;
        if (request.Path.Value.StartsWith("/apiendpoint", StringComparison.OrdinalIgnoreCase))
        {           
            var json = JsonConvert.SerializeObject(request.Path.Value
                .Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries)
                .Skip(1));
            var response = context.HttpContext.Response;

            response.Headers[HeaderNames.Location] = $"/custom";
            response.StatusCode = StatusCodes.Status301MovedPermanently;
            context.Result = RuleResult.EndResponse;
            using (var bodyWriter = new StreamWriter(response.Body))
            {
                bodyWriter.Write(json);
                bodyWriter.Flush();
            }
        }
    }
问题是,当它重定向到/customurl时,request有方法GET,而这个方法需要POST

例如,将GET请求发送到url/apiendpoint/first/second/third,然后重写器响应重定向,因此,下面的请求必须使用方法POST,但现在是GET


如何更改url重写器响应后的请求方法?

这是一个示例代码

public class ConvertGetToPostHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // Add your logic here to decide if the request Method needs to be changed
        // Caution: This works only if you're redirecting internally
        request.Method = HttpMethod.Post;
        return await base.SendAsync(request, cancellationToken);
    }
}
公共类ConvertGetToPostHandler:DelegatingHandler
{
受保护的覆盖异步任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
//在此处添加逻辑以决定是否需要更改请求方法
//警告:这仅在内部重定向时有效

request.Method=HttpMethod.Post; 返回wait base.sendaync(请求、取消令牌); } }
您必须将处理程序添加到处理程序管道中,如下所示:

config.MessageHandlers.Add(新的ConvertGetToPostHandler())


另外,仔细阅读这篇文章,了解它的用途和用法。

编辑:啊,刚才查看了评论。如果最初的请求是GET,那么这也不起作用,您不能告诉浏览器发布。如果不返回一个使用JavaScript自动执行表单的视图,则不能这样做

您需要返回308,而不是301

以下是更改后的代码:

private static void RedirectToAPI(RewriteContext context)
{
    var request = context.HttpContext.Request;
    if (request.Path.Value.StartsWith("/apiendpoint", StringComparison.OrdinalIgnoreCase))
    {           
        var json = JsonConvert.SerializeObject(request.Path.Value
            .Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries)
            .Skip(1));
        var response = context.HttpContext.Response;

        response.Headers[HeaderNames.Location] = $"/custom";
        response.StatusCode = 308;
        context.Result = RuleResult.EndResponse;
        using (var bodyWriter = new StreamWriter(response.Body))
        {
            bodyWriter.Write(json);
            bodyWriter.Flush();
        }
    }
}
308是一个永久重定向,要求浏览器保留该方法

临时版本是307


MVC Core 2.0.0-preview1中提供了这些重定向的方便方法。

您能否将@juunas answer设置为正确答案,他的答案为我解决了这个问题,正如您在示例代码中看到的那样

internal class RedirectCultureRule : IRule
{
    private const string CultureKey = "culture";

    public void ApplyRule(RewriteContext context)
    {
        HttpRequest httpRequest = context.HttpContext.Request;
        httpRequest.Query.TryGetValue(CultureKey, out StringValues cultureValues);
        string culture = cultureValues;

        if (cultureValues.Count > 0 && culture.IsCultureMatch())
        {
            context.Result = RuleResult.ContinueRules;
            return;
        }

        Dictionary<string, string> queryParts = new Dictionary<string, string>();
        NameValueCollection queryString = HttpUtility.ParseQueryString(httpRequest.QueryString.ToString());

        foreach (string key in queryString)
        {
            queryParts[key.Trim()] = queryString[key].Trim();
        }

        if (!queryParts.ContainsKey(CultureKey))
        {
            queryParts[CultureKey] = CultureInfo.CurrentCulture.Name;
        }

        string query = $"?{string.Join("&", queryParts.Select(qp => $"{qp.Key}={qp.Value}"))}";

        if (query.Length > 1)
        {
            httpRequest.QueryString = new QueryString(query);
        }

        string url = UriHelper.GetDisplayUrl(httpRequest);

        HttpResponse httpResponse = context.HttpContext.Response;
        httpResponse.StatusCode = 308;
        httpResponse.Headers[HeaderNames.Location] = url;

        using (StreamReader requestReader = new StreamReader(httpRequest.Body))
        {
            using (StreamWriter responseWriter = new StreamWriter(httpResponse.Body))
            {
                string body = requestReader.ReadToEnd();
                responseWriter.Write(body);
                responseWriter.Flush();
            }
        }

        context.Result = RuleResult.EndResponse;
    }
}
内部类重定向culturerule:IRule
{
private const string CultureKey=“culture”;
public void ApplyRule(重写上下文)
{
HttpRequest HttpRequest=context.HttpContext.Request;
httpRequest.Query.TryGetValue(CultureKey,out-StringValues-cultureValues);
字符串区域性=cultureValues;
如果(cultureValues.Count>0&&culture.IsCultureMatch())
{
context.Result=RuleResult.ContinueRules;
返回;
}
Dictionary queryParts=new Dictionary();
NameValueCollection queryString=HttpUtility.ParseQueryString(httpRequest.queryString.ToString());
foreach(查询字符串中的字符串键)
{
queryParts[key.Trim()]=queryString[key].Trim();
}
如果(!queryParts.ContainsKey(CultureKey))
{
queryParts[CultureKey]=CultureInfo.CurrentCulture.Name;
}
字符串查询=$“?{string.Join(&),queryParts.Select(qp=>$”{qp.Key}={qp.Value}”))}”;
如果(query.Length>1)
{
httpRequest.QueryString=新的QueryString(查询);
}
字符串url=UriHelper.GetDisplayUrl(httpRequest);
HttpResponse HttpResponse=context.HttpContext.Response;
httpResponse.StatusCode=308;
httpResponse.Headers[HeaderNames.Location]=url;
使用(StreamReader requestReader=newstreamreader(httpRequest.Body))
{
使用(StreamWriter responseWriter=newstreamwriter(httpResponse.Body))
{
字符串体=requestReader.ReadToEnd();
写作(正文);
responseWriter.Flush();
}
}
context.Result=RuleResult.EndResponse;
}
}

如果使用ASP.NET Core 2.0有RedirectPermanentPreserve方法,您可以阅读它。如果此方法不受支持,您可以尝试手动执行。

您是否尝试了
request.method=“POST”
?@Gururaj是的,没有任何更改,仍然获取request.request.method=HttpMethod.POST@古鲁拉和以前的完全一样。然而,
request.Method
在重写之前更改了传入请求的方法,而我需要在.Gosh!之后更改!,我怎么会错过这个-我的道歉。查看您的代码,我发现您没有在服务器上进行内部重定向,而是创建了一个响应,将请求重定向到另一个URI。您是否尝试使用
DelegatingHandler
实现和重写
SendAsync
方法来更改请求方法。除非您不尝试重定向到外部URI,否则这是有效的。ASP.NET核心中没有DelegatingHandler。是用来代替抱歉的伴侣的。看来今天不是我的好日子。对不起,浪费了你的时间。我还没有在Core上工作过:(检查此参考,如果有帮助您的方法很好,尽管如前所述,在Asp.Net Core中有中间件,这正是我寻找的目的。@YuriyN。感谢您确认我的方法。我之前共享了一个参考,其中描述了从处理程序迁移到核心中间件的过程。请阅读此参考,看看是否那对你有任何帮助。