I'm using this class for having clean URLs in my application :
public static class UrlEncoder
{
public static string ToFriendlyUrl(this UrlHelper helper,
string urlToEncode)
{
urlToEncode = (urlToEncode ?? "").Trim().ToLower();
StringBuilder url = new StringBuilder();
foreach (char ch in urlToEncode)
{
switch (ch)
{
case ' ':
url.Append('-');
break;
case '&':
url.Append("and");
break;
case '\'':
break;
default:
if ((ch >= '0' && ch <= '9') ||
(ch >= 'a' && ch <= 'z'))
{
url.Append(ch);
}
else
{
url.Append('-');
}
break;
}
}
return url.ToString();
}
}
and I'm using above class with this way :
#item.Name
but I'm getting this error and extension not working:
Compiler Error Message: CS1061: 'System.Web.Mvc.UrlHelper' does not contain a definition for 'ToFriendlyUrl' and no extension method 'ToFriendlyUrl' accepting a first argument of type 'System.Web.Mvc.UrlHelper' could be found (are you missing a using directive or an assembly reference?)
I've added these using directive :
using System;
using System.Text;
using System.Web.Mvc;
I tried this method but still I have same error :
#UrlHelper.ToFriendlyUrl(item.Name)
and used this directive using System.Web.Http.Routing; instead using System.Web.Mvc;but still I have same error.
it seems that UrlHelper belongs to another assembly , I don't know.
any Ideas?
Thanks in your Advise
You also need to include the namespace of UrlEncoder class in your view:
#using Mynamespace
I encountered a similar error when calling a UrlHelper extension method from my view, but the solution was slightly different so I'll share it in case it helps someone else:
In my extension class, I needed to replace using System.Web.Http.Routing; with using System.Web.Mvc;
Both resolve UrlHelper, but the MVC reference is what you need to use it in your view.
Pass the interface(IUrlHelper) instead of class name(UrlHelper) as first parameter.
public static class UrlEncoder
{
public static string ToFriendlyUrl(this **IUrlHelper** helper,
string urlToEncode)
{
//your code
}
}
Related
I wanted to create a page render with ContentPage type. I created so in android and it is working but in IOS there has custom page renderer with same type (ContentPage). It can be removed as this was from nuget package and working on different context.
Here is my code
[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomPageRenderer))]
namespace AlwinInvoiceGenerator.IOS
{
using CoreGraphics;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
public class CustomPageRenderer : PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
if (Element == null || !(Element is ContentPage basePage) || basePage.BindingContext == null ||
!(basePage.BindingContext is BaseViewModel baseViewModel))
{
return;
}
SetCustomBackButton(baseViewModel);
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
OverrideUserInterfaceStyle = UIUserInterfaceStyle.Light;
}
private void SetCustomBackButton(BaseViewModel baseViewModel)
{
var fakeButton = new UIButton {Frame = new CGRect(0, 0, 50, 40), BackgroundColor = UIColor.Clear};
fakeButton.TouchDown += (sender, e) =>
{
baseViewModel.OnBackButtonClicked();
};
NavigationController?.NavigationBar.AddSubview(fakeButton);
}
}
It seems it not registering and that is why not calling.
I have another page renderer that is register in assembly
[assembly: ExportRenderer(typeof(ContentPage), typeof(IOSToolbarExtensions.iOS.Renderers.IOSToolbarExtensionsContentPageRenderer), Priority = short.MaxValue)]
If I removed this line then above code is working but not two in the same time.
Please help
Same type seems not working for multiple renderer.
I have created sub type of my custom renderer and override the methods which needed to. It is working well
I have a static class, example:
public static Config
{
public static string ServerIP;
...
}
I made this static, because it can be easily accessed across the entire application.
The problem now is, how can I serialize / deserialize it? Because these configuration will change and using might modify the value in the json file.
Neither System.Text.Json nor Newtonsoft.Json support serialization of static classes. So while you can't serialize the class directly, you can serialize its members.
If you can use Newtonsoft.Json, then you can shim something like this at least for deserialization, and something similar for serialization:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
static class Config
{
public static string ServerIP = string.Empty;
}
static void DeserializeStaticClass(string json, Type staticClassType)
{
if (!staticClassType.IsClass)
throw new ArgumentException("Type must be a class", nameof(staticClassType));
if (!staticClassType.IsAbstract || !staticClassType.IsSealed)
throw new ArgumentException("Type must be static", nameof(staticClassType));
var document = JObject.Parse(json);
var classFields = staticClassType.GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (var field in classFields)
{
var documentField = document[field.Name];
if (documentField == null)
throw new JsonSerializationException($"Not found in JSON: {field.Name}");
field.SetValue(null, documentField.ToObject(field.FieldType));
}
}
...
DeserializeStaticClass("{\"ServerIP\": \"localhost\"}", typeof(Config));
If you need to customize serialization of nested members, you can pass a JsonSerializer to documentField.ToObject.
I realize this Q is a bit old, but here's what I do...
In my static class, I make a method that materializes the class' data and returns it as an object. Then this can be used to pass in to NewtonSoft or whatever other serialization you use.
As example, here is my method in my static (INI) class:
public static dynamic Materialize() {
return new {
Web = Web,
Client = Client,
Logging = Logging
};
}
and then I can easily call this and effectively serialize my class, like so:
if(Arguments.Verbose) {
var json = JsonConvert.SerializeObject(INI.Materialize(), Formatting.Indented);
Logging.Log($"INI Configuration:\n{json}");
}
I have installed and used Microsoft.Web.RedisSessionStateProvider for a while and after looking at OutputCaching I thought of installing Microsoft.Web.RedisOutputCacheProvider as well but they both have Microsoft.Web.Redis.ISerializer interface which breaks my JsonCacheSerializer as it uses the ISerializer interface.
I am getting an error in VS 2017, which reads ...
"The type 'ISerializer' exists in both Microsoft.Web.RedisOutputCacheProvider and Microsoft.Web.RedisSessionStateProvider"
The JsonCacheSerializer code I use for SessionState is :
public class JsonCacheSerializer : Microsoft.Web.Redis.ISerializer
{
private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.All,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
Error = (serializer, err) => {
err.ErrorContext.Handled = true;
}
};
public byte[] Serialize(object data)
{
return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data, Settings));
}
public object Deserialize(byte[] data)
{
return data == null ? null : JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), Settings);
}
}
Does this mean one has to use one or the other, not both?
You may use extern alias feature of C#
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extern-alias
Visual Studio example:
1) right click Microsoft.Web.RedisOutputCacheProvider and put following into Aliases field:
global,redisoutputcacheprovider
2) right click Microsoft.Web.RedisSessionStateProvider and put following into Aliases field:
global,redissessionstateprovider
then on top of your code file add:
extern alias redissessionstateprovider;
extern alias redisoutputcacheprovider;
and finally declare your class as:
public class JsonCacheSessionStateSerializer : redissessionstateprovider::Microsoft.Web.Redis.ISerializer
I have a Nancy module which uses a function which expects as parameters a string (a captured pattern from a route) and a method group. When trying to pass the parameter directly it will not compile as I "cannot use a method group as an argument to a dynamically dispatched operation".
I have created a second route which attempts to cast the dynamic to a string, but this always returns null.
using System;
using Nancy;
public class MyModule : NancyModule
{
public MyModule()
{
//Get["/path/{Name}/action"] = parameters =>
// {
// return MyMethod(parameters.Name, methodToBeCalled); // this does not compile
// };
Get["/path/{Name}/anotherAction"] = parameters =>
{
return MyMethod(parameters.Name as string, anotherMethodToBeCalled);
};
}
public Response MyMethod(string name, Func<int> doSomething)
{
doSomething();
return Response.AsText(string.Format("Hello {0}", name));
}
public int methodToBeCalled()
{
return -1;
}
public int anotherMethodToBeCalled()
{
return 1;
}
}
Tested with the following class in a separate project:
using System;
using Nancy;
using Nancy.Testing;
using NUnit.Framework;
[TestFixture]
public class MyModuleTest
{
Browser browser;
[SetUp]
public void SetUp()
{
browser = new Browser(with =>
{
with.Module<MyModule>();
with.EnableAutoRegistration();
});
}
[Test]
public void Can_Get_View()
{
// When
var result = browser.Get("/path/foobar/anotherAction", with => with.HttpRequest());
// Then
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
Assert.AreEqual("Hello foobar", result.Body.AsString()); //fails as parameters.Name is always null when cast to a string
}
}
You can find the whole test over on github
I've had similar issues when using 'as' so I tend to use explicitly cast it:
return MyMethod((string)parameters.Name, anotherMethodToBeCalled);
Also I think there was a bug raised with the casing on parameters, but I think it's better to keep them lowercase:
Get["/path/{name}/anotherAction"]
(string)parameters.name
Your code works for me with upper case and lowercase, using the explicit cast.
I'm developing WCF services where some classes have the [MessageContract] attribute, and some don't.
When I try to run the services I get this error message below:
The operation 'ProcessOperation' could not be loaded because it has a parameter or return type of type System.ServiceModel.Channels.Message or a type that has MessageContractAttribute and other parameters of different types. When using System.ServiceModel.Channels.Message or types with MessageContractAttribute, the method must not use any other types of parameters.
Does it mean that all the services must have [MessageContract] although they are not related?
No, it means that you have multiple parameters on the method and some of them are not messages. Try posting the interface to your service.
This blog post explains:
... problem is that message contracts cannot be used at the same time as other parameter types. In this case, the return value of the operation is a string. Return values are just another output parameter, so this operation is mixing a message contract message with a primitive parameter type. This fails because message contracts give you control of the layout of the SOAP message, preventing the system from melding in these additional parameters.
Important note:
By the way, the error message you get when you try to mix message contracts looks like this.
This basically means that a particular operation is using a combination of message contract types and primitive types in any of the following combinations:
MixType1: Contract type and primitive types as operation parameters
MixType2: Contract type as a parameter and primitive type as return type
MixType3: Primitive type as a parameter and Contract type as return type
Any of the scenarios listed above would generate the error.
Solved!
I can't return String, I have return Greeting object to the client.
using System;
using System.ServiceModel;
using System.Net.Security;
namespace com.blogspot.jeanjmichel.model
{
[MessageContract]
public class Greeting
{
private String userGreeting;
private void SetGreeting()
{
DateTime now = DateTime.Now;
if (now.Hour >= 7 && now.Hour <= 11)
{
this.userGreeting = "Good morning";
}
else if (now.Hour >= 12 && now.Hour <= 17)
{
if (now.Hour == 12 || now.Hour == 13)
{
this.userGreeting = "Good afternoon, it's lunch time!";
}
else
{
this.userGreeting = "Good afternoon";
}
}
else if (now.Hour >= 18 && now.Hour <= 20)
{
this.userGreeting = "Good evening";
}
else
{
this.userGreeting = "Good night";
}
}
[MessageBodyMember(Order = 1, ProtectionLevel = ProtectionLevel.EncryptAndSign)]
public String UserGreeting
{
get { return this.userGreeting; }
}
public Greeting()
{
this.SetGreeting();
}
}
}
using System;
using System.ServiceModel;
using com.blogspot.jeanjmichel.model;
namespace com.blogspot.jeanjmichel.services.contract
{
[ServiceContract(Namespace = "http://jeanjmichel.blogspot.com/services/v0.0.1")]
public interface IGetGreeting
{
[OperationContract]
Greeting GetGreeting(Credential credential);
}
}
using System;
using System.ServiceModel;
using com.blogspot.jeanjmichel.services.contract;
using com.blogspot.jeanjmichel.model;
namespace com.blogspot.jeanjmichel.services
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
Namespace = "http://jeanjmichel.blogspot.com/services/v0.0.1")]
public class GetGreetingService: IGetGreeting
{
public Greeting GetGreeting(Credential credential)
{
if (String.IsNullOrEmpty(credential.Token))
{
throw new FaultException("Inform the security phrase, and try again.");
}
else
{
if (credential.Token.Equals("mySeCuriTyP#ss"))
{
Greeting g = new Greeting();
return g;
}
else
{
throw new FaultException("Wrong password.");
}
}
}
}
}
When you are using Message object as a parameter, the method should return void
If you have the issue with mixed types of primitive(such as string) and MessageContract as the other type, i.e. one class as return and a string parameter, one way I solved this was switching from MessageContract to DataContract.
The other way to solve this would be to create a class to hold your primitive type as a property, so that both your return and parameter can implement MessageContract.
I ran into this error while maintaining an API in our code. The API suddenly began returning this error for all endpoints.
I had upgraded the initialization method for Ninject to move away from a method that it said was obsolete.
Obsolete method: NinjectWebServiceHostFactory (no error)
New method: NinjectServiceHostFactory (returns error)
The error went away when I reverted the change.