I have an MVC method:
public void PushFile([FromBody]FileTransport fileData)
Class is:
public class FileTransport
{
public string fileData;
}
In fileData I put byte[] from a file converted into a string (UTF-8), so the string can be large.
Problem is: if the string is too large (somewhere above 15000 characters) the fileData parameter is null. If the string is not that large, everything works fine and the parameter is as it should be.
How can I allow MVC to accept larger strings, or do I need to compress the string somehow beforehand?
EDIT:
Already tried:
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="2147483644"/>
</webServices>
</scripting>
</system.web.extensions>
But does not work. Maybe because MVC uses JSON.NET instead of the normal JsonSerializer?
Did you try to increase max length of the request?
<system.web>
<httpRuntime maxRequestLength="{REQUEST_LENGTH}"/>
<system.web>
Simple Point is - you dont put the string into the URL. Simple like that. Add it as payload. URL's are ressource locators, not "Content carriers".
I figured out it had nothing to do with content length. If seems like the Json does not encode properly with some characters on the sender's side, that's when MVC controller recieved null.
Related
In my ASP.NET MVC 4 application I have an action on controller that gets URL string as a parameter:
public ActionResult Get(string url)
{
var hash = TextUtil.GenerateShortStringHash(url);
...
return Content(html, "text/html");
}
The request looks like this: http://localhost:37779/api/get/http:%2F%2Fwww.mysite.com
But on some level application automatically replaces double slashes with single one.
Where does this happen? Is there any way to prevent such behavior? Thanks.
My suspicion is that because it's part of the hierarchical portion of the URL it's automatically converting the double slashes to a single slash because double slashes aren't allowed in that portion of the URL. Because URLs contain characters that aren't allowed in the hierarchical portion of the URL, it's best to specify it (suitably encoded) as part of the query string (if a GET request) or in the form parameters (for a POST).
http://localhost:37779/api/get/?url=http:%2F%2Fwww.mysite.com
I completely agree with #tvanfosson that such special characters should be passed as a query string parameter instead of using the path portion of the url. Scott Hanselman wrote a nice blog post explaining the challenges you will face if you attempt to pass such characters.
This being said, you could make it work using double encoding:
http://localhost:37779/api/get/http%253A%252F%252Fwww.mysite.com
and in your controller action:
public ActionResult Get(string url)
{
var hash = TextUtil.GenerateShortStringHash(HttpUtility.UrlDecode(url));
...
return Content(html, "text/html");
}
In order for this to work you need to add the following to your web.config to enable double encoding:
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true"/>
</security>
</system.webServer>
and also explicitly define the invalid characters so that : and / are not part of them or you will get 400 Bad Request:
<system.web>
<httpRuntime requestPathInvalidCharacters="<,>" />
</system.web>
I have an controller called Test Controller and the method name is Test
The Test Method accepts one parameter. But when the parameter contains value having space slash the web api is giving error. I am using WEB API 2.
[Route("Test/{companyName}")]
[AcceptVerbs("GET", "POST")]
[System.Web.HHttpGet]
public HttpResponseMessage Test(string companyName)
{
}
the parameter value is BTL / Force Motor Ltd.
I have tried but nothing happened.
<uri>
<schemeSettings>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
</schemeSettings>
</uri>
You need to URL Encode the values you are sending to your API, like this:
http://yourApiDomainName/api/yourControllerName/?companyName=BTL%20%2F%20Force%20Motor%20Ltd
[SPACE] when URL encoded beomes: %20
[Forward Slash] when URL encoded becomes: %2F
you dont need to http decode the values in your controller, as these values will be decoded by the framework as soon as they reach your controller. So you will see 'BTL%20%2F%20Force%20Motor%20Ltd' as 'BTL / Force Motor Ltd' inside your controller.
for full list of URL Encodings see this:
http://www.w3schools.com/tags/ref_urlencode.asp
Your issue has nothing to do with WebAPI itself but how ASP.Net handles some specific Urls. This may also affect any dots (".") that get passed in to your API. Here's what worked for me:
Add this line to your web.config under system.web
<httpRuntime relaxedUrlToFileSystemMapping="true" />
Phil Haacked has a great article that goes into more detail.
I'm using breezejs to handle my entities on a web application.
Specifically i start with the Angular HotTowel template.
The problem i'm having is that i'm sending a large json array of objects (length about 17000) so on my controller im getting null on the parameter to receive this information.
When I try to send less data an array of 5000 objects then the controller parameter is setted with the objects correctlly.
My controller
[BreezeController]
public class SoftProductsController : ApiController
{
private readonly EFContextProvider<Context> contextProvider = new EFContextProvider<Context>();
[HttpGet]
public string Metadata()
{
return this.contextProvider.Metadata();
}
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
//Here saveBundle is NULL
return this.contextProvider.SaveChanges(saveBundle);
}
}
Could be this related to some json deserialization on WebApi when using large json data?
I tried setting this option on the web.congif with no success
<appSettings>
<add key="aspnet:MaxJsonDeserializerMembers" value="20000"/>
</appSettings>
I'm using .NET 4.5
Any idea?
My problem was the default limit on requestLenght that ASP.NET have.
Increasing that limit on the web.config allow breeze to post large data.
(default size is 4096 KB)
<system.web>
<httpRuntime targetFramework="4.5" maxRequestLength="5120" />
</system.web>
https://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.maxrequestlength(v=vs.110).aspx
I need a way to configure my contract (method) to take a variable number of parameters. Because you should be able to pass 2 or 10 parameters to this end point.
Btw, the reason I return a Stream is because I serialize my data to XML manually (not important).
ServiceInterface:
[OperationContract]
Stream UpdateAgent(string token, string agentId, string newAgentName, string param1);
Service implementation:
[WebGet(UriTemplate = "/update_agent/{token}/{agentId}/{newAgentName}/{param1}")]
public Stream UpdateAgent(string token, string agentId, string newAgentName, string param1)
{
//do stuff here
}
This method is only available with this URI request:
/update_agent/<long number of chars and numbers>/123456/John Silver/<some ID of associated data>
But I want to be able to pass more params of strings, if I want to. I know that alters the end point of the contract - but is this possible?
To clarify, the following should trigger the same endpoint:
/update_agent/<long number of chars and numbers>/123456/John Silver/dom_81/pos_23
/update_agent/<long number of chars and numbers>/123456/John Silver/dom_120/dat_12/pos_10
/update_agent/<long number of chars and numbers>/123456/John Silver/con_76
Can anyone help me - because clearly I can't make 10,000 methods taking care of each extra parameter...
This does not appear to be supported.
However, Microsoft has been made aware of this issue and there is a work-around:
You can get the desired effect by
omitting the Query string from the
UriTemplate on your WebGet or
WebInvoke attribute, and using
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters
from within your handlers to inspect,
set defaults, etc. on the query
parameters.
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=451296&wa=wsignin1.0
From SO : Optional query string parameters in URITemplate in WCF?
I have solved my own problem, by doing the following:
Installing URL Rewrite 2.0 (link)
Configured a rewrite rule through my Web.config file:
Web.config section: configuration/system.webServer/
<rules>
<rule name="UpdateAgentUrlRewrite" stopProcessing="true">
<match url="^service/update_agent/([^/]+)/(agent_\d+)/([^/]+)/(.*)$" />
<action type="Rewrite" url="Service.svc/update_agent/{R:1}/{R:2}/{R:3}?input={R:4}" appendQueryString="false" logRewrittenUrl="true" />
</rule>
</rules>
This regex, I made, will transform an URL like this:
/service/update_agent/123a456b789c012d/agent_1/New Agent Name/d_1/e_2/f_3/g_4
||
/Service/update_agent/123a456b789c012d/agent_1/New%20Agent%20Name?input=d_1/e_2/f_3/g_4
Which means I can hit the same Service Endpoint no matter how much I append in the URL, and then just extract the query parameters with this code:
var context = WebOperationContext.Current;
if(context != null)
{
NameValueCollection queryParams = context.IncomingRequest.UriTemplateMatch.QueryParameters;
//contains a keyvalue pair:
// {
// key = "input";
// value = "e_2/f_3/g_4";
// }
}
You can do a template like so:
/update_agent/{token}/{agentId}/{newAgentName}/{*params}
to put the rest of the path into the params variable, and then parse each param out for yourself inside the method.
Suppose I have an asmx web service at the following address:
http://localhost/BudgetWeb/Service.asmx
This web service has a web method with the following signature:
string GetValue(string key)
This GetValue method returns a string like this:
<?xml version=\"1.0\" encoding=\"utf-8\" ?><value>250.00</value>
What if I wanted to do this:
XDocument doc = XDocument.Load("http://localhost/BudgetWeb/Service.asmx?op=GetValue&key=key1")
This doesn't work, and I'm pretty sure that XDocument.Load doesn't actually invoke a web method on the server. I think it expects the uri to point to a file that it can load. To call a web method, I think I'd have to have a web proxy class and would have to use that to call string GetValue(string key), and then I could use that value returned from the web proxy class to pass to the XDocument.Load method.
Is my understanding correct, or is there a way for XDocument.Load to actually invoke a web method on the server?
Try to use this:
XDocument doc = XDocument.Load(
"http://localhost/BudgetWeb/Service.asmx/GetValue?key=key1");
EDIT: Just figured out: you're using a invalid URI:
http://localhost/BudgetWeb/Service.asmx?op=GetValue&key=key1
Should be
http://localhost/BudgetWeb/Service.asmx/GetValue?key=key1
I'm using this code snippet:
string uri = "http://www.webservicex.net/stockquote.asmx/GetQuote?symbol=MSFT";
XDocument doc1 = XDocument.Load(uri);
Console.WriteLine(doc1.Root.Value); // <StockQuotes><Stock><Symbol>MSFT...
Ok, I found the issue. In the web.config for the web service, you have to add this:
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
Thanks to everyone for their suggestions, I really appreciate it, especially Rubens Farias whose working example put me on the right track.